Exemplo n.º 1
0
        void WriteArrayItems(ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc, string arrayName, string choiceName) {
            TypeDesc arrayElementTypeDesc = arrayTypeDesc.ArrayElementTypeDesc;

            if (arrayTypeDesc.IsEnumerable) {
                Writer.Write(typeof(IEnumerator).FullName);
                Writer.Write(" e = ");
                if (arrayTypeDesc.IsPrivateImplementation) {
                    Writer.Write("((");
                    Writer.Write(typeof(IEnumerable).FullName);
                    Writer.Write(")");
                    Writer.Write(arrayName);
                    Writer.WriteLine(").GetEnumerator();");
                }
                else if(arrayTypeDesc.IsGenericInterface) {
                    if (arrayTypeDesc.UseReflection) {
                        // we use wildcard method name for generic GetEnumerator method, so we cannot use GetStringForMethodInvoke call here
                        Writer.Write("(");
                        Writer.Write(typeof(IEnumerator).FullName);
                        Writer.Write(")");
                        Writer.Write(RaCodeGen.GetReflectionVariable(arrayTypeDesc.CSharpName, "System.Collections.Generic.IEnumerable*"));
                        Writer.Write(".Invoke(");
                        Writer.Write(arrayName);
                        Writer.WriteLine(", new object[0]);");
                    }
                    else {
                        Writer.Write("((System.Collections.Generic.IEnumerable<");
                        Writer.Write(arrayElementTypeDesc.CSharpName);
                        Writer.Write(">)");
                        Writer.Write(arrayName);
                        Writer.WriteLine(").GetEnumerator();");
                    }
                }
                else {
                    if (arrayTypeDesc.UseReflection) {
                        Writer.Write("(");
                        Writer.Write(typeof(IEnumerator).FullName);
                        Writer.Write(")");
                    }
                    Writer.Write(RaCodeGen.GetStringForMethodInvoke(arrayName, arrayTypeDesc.CSharpName, "GetEnumerator", arrayTypeDesc.UseReflection));
                    Writer.WriteLine(";");
                }
                Writer.WriteLine("if (e != null)");
                Writer.WriteLine("while (e.MoveNext()) {");
                Writer.Indent++;
                string arrayTypeFullName = arrayElementTypeDesc.CSharpName;
                WriteLocalDecl(arrayTypeFullName, arrayName+"i", "e.Current", arrayElementTypeDesc.UseReflection);
                WriteElements(arrayName + "i", choiceName + "i", elements, text, choice, arrayName + "a", true, true);
            }
            else {
                Writer.Write("for (int i");
                Writer.Write(arrayName);
                Writer.Write(" = 0; i");
                Writer.Write(arrayName);
                Writer.Write(" < ");
                if (arrayTypeDesc.IsArray) {
                    Writer.Write(arrayName);
                    Writer.Write(".Length");
                }
                else {
                    Writer.Write("((");
                    Writer.Write(typeof(ICollection).FullName);
                    Writer.Write(")");
                    Writer.Write(arrayName);
                    Writer.Write(").Count");
                }
                Writer.Write("; i");
                Writer.Write(arrayName);
                Writer.WriteLine("++) {");
                Writer.Indent++;
                int count = elements.Length + (text == null ? 0 : 1);
                if (count > 1) {
                    string arrayTypeFullName = arrayElementTypeDesc.CSharpName;
                    WriteLocalDecl(arrayTypeFullName, arrayName+"i", RaCodeGen.GetStringForArrayMember(arrayName, "i"+arrayName, arrayTypeDesc), arrayElementTypeDesc.UseReflection);
                    if (choice != null) {
                        string choiceFullName = choice.Mapping.TypeDesc.CSharpName;
                        WriteLocalDecl(choiceFullName, choiceName+"i", RaCodeGen.GetStringForArrayMember(choiceName, "i"+arrayName, choice.Mapping.TypeDesc), choice.Mapping.TypeDesc.UseReflection);
                    }
                    WriteElements(arrayName + "i", choiceName + "i", elements, text, choice, arrayName + "a", true, arrayElementTypeDesc.IsNullable);
                }
                else {
                    WriteElements(RaCodeGen.GetStringForArrayMember(arrayName , "i" + arrayName, arrayTypeDesc), elements, text, choice, arrayName + "a", true, arrayElementTypeDesc.IsNullable);
                }
            }
            Writer.Indent--;
            Writer.WriteLine("}");
        }
Exemplo n.º 2
0
 protected AccessorMapping(AccessorMapping mapping)
     : base(mapping)
 {
     _typeDesc = mapping._typeDesc;
     _attribute = mapping._attribute;
     _elements = mapping._elements;
     _sortedElements = mapping._sortedElements;
     _text = mapping._text;
     _choiceIdentifier = mapping._choiceIdentifier;
     _xmlns = mapping._xmlns;
     _ignore = mapping._ignore;
 }
Exemplo n.º 3
0
 void WriteMember(string source, string choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc memberTypeDesc, bool writeAccessors) {
     if (memberTypeDesc.IsArrayLike && 
         !(elements.Length == 1 && elements[0].Mapping is ArrayMapping))
         WriteArray(source, choiceSource, elements, text, choice, memberTypeDesc);
     else
         WriteElements(source, choiceSource, elements, text, choice, "a", writeAccessors, memberTypeDesc.IsNullable);
 }
        private void WriteArray(object o, object choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc)
        {
            if (elements.Length == 0 && text == null)
            {
                return;
            }

            if (arrayTypeDesc.IsNullable && o == null)
            {
                return;
            }

            if (choice != null)
            {
                if (choiceSource == null || ((Array)choiceSource).Length < ((Array)o).Length)
                {
                    throw CreateInvalidChoiceIdentifierValueException(choice.Mapping.TypeDesc.FullName, choice.MemberName);
                }
            }

            WriteArrayItems(elements, text, choice, arrayTypeDesc, o);
        }
        private void WriteElements(object o, object enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable, XmlMapping parentMapping = null)
        {
            if (elements.Length == 0 && text == null) return;
            if (elements.Length == 1 && text == null)
            {
                WriteElement(o, elements[0], arrayName, writeAccessors, parentMapping);
            }
            else
            {
                if (isNullable && choice == null && o == null)
                {
                    return;
                }

                int anyCount = 0;
                var namedAnys = new List<ElementAccessor>();
                ElementAccessor unnamedAny = null; // can only have one
                string enumTypeName = choice == null ? null : choice.Mapping.TypeDesc.FullName;

                for (int i = 0; i < elements.Length; i++)
                {
                    ElementAccessor element = elements[i];

                    if (element.Any)
                    {
                        anyCount++;
                        if (element.Name != null && element.Name.Length > 0)
                            namedAnys.Add(element);
                        else if (unnamedAny == null)
                            unnamedAny = element;
                    }
                    else if (choice != null)
                    {
                        if (o != null && o.GetType() == element.Mapping.TypeDesc.Type)
                        {
                            WriteElement(o, element, arrayName, writeAccessors);
                            return;
                        }
                    }
                    else
                    {
                        TypeDesc td = element.IsUnbounded ? element.Mapping.TypeDesc.CreateArrayTypeDesc() : element.Mapping.TypeDesc;
                        if (o.GetType() == td.Type)
                        {
                            WriteElement(o, element, arrayName, writeAccessors);
                            return;
                        }
                    }
                }

                if (anyCount > 0)
                {
                    var elem = o as XmlElement;
                    if (elem != null)
                    {
                        foreach (ElementAccessor element in namedAnys)
                        {
                            if (element.Name == elem.Name && element.Namespace == elem.NamespaceURI)
                            {
                                WriteElement(elem, element, arrayName, writeAccessors);
                                return;
                            }
                        }

                        if (choice != null)
                        {
                            throw CreateChoiceIdentifierValueException(choice.Mapping.TypeDesc.FullName, choice.MemberName, elem.Name, elem.NamespaceURI);
                        }

                        if (unnamedAny != null)
                        {
                            WriteElement(elem, unnamedAny, arrayName, writeAccessors);
                            return;
                        }

                        throw CreateUnknownAnyElementException(elem.Name, elem.NamespaceURI);
                    }
                }

                if (text != null)
                {
                    bool useReflection = text.Mapping.TypeDesc.UseReflection;
                    string fullTypeName = text.Mapping.TypeDesc.CSharpName;
                    WriteText(o, text);
                    return;
                }

                if (elements.Length > 0 && o != null)
                {
                    throw CreateUnknownTypeException(o);
                }
            }
        }
        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) {
                ILGenSet(checkSpecified, true);
            }

            if (element.Mapping is ArrayMapping) {
                WriteArray(source, arrayName, (ArrayMapping)element.Mapping, readOnly, element.IsNullable, fixupIndex, elementIndex);
            }
            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(Res.GetString(Res.XmlInternalErrorMethod, element.Mapping.TypeDesc.Name));
#endif
                WriteSourceBegin(source);
                ilg.Ldarg(0);
                ilg.Ldc(true);
                MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
                    methodName,
                    CodeGenerator.PrivateMethodAttributes,
                    // See WriteNullableMethod for different return type logic
                    element.Mapping.TypeDesc.Type,
                    new Type[] { typeof(Boolean) }
                    );
                ilg.Call(methodBuilder);
                WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
            }
            else if (element.Mapping is PrimitiveMapping) {
                bool doEndIf = false;
                if (element.IsNullable) {
                    MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod(
                         "ReadNull",
                         CodeGenerator.InstanceBindingFlags,
                         null,
                         CodeGenerator.EmptyTypeArray,
                         null
                         );
                    ilg.Ldarg(0);
                    ilg.Call(XmlSerializationReader_ReadNull);
                    ilg.If();
                    WriteSourceBegin(source);
                    if (element.Mapping.TypeDesc.IsValueType) {
                        throw CodeGenerator.NotSupported("No such condition.  PrimitiveMapping && IsNullable = String, XmlQualifiedName and never IsValueType");
                    }
                    else {
                        ilg.Load(null);
                    }
                    WriteSourceEnd(source, element.Mapping.TypeDesc.Type);
                    ilg.Else();
                    doEndIf = true;
                }
                if (element.Default != null && element.Default != DBNull.Value && element.Mapping.TypeDesc.IsValueType) {
                    MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
                        "get_Reader",
                        CodeGenerator.InstanceBindingFlags,
                        null,
                        CodeGenerator.EmptyTypeArray,
                        null
                        );
                    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);
                    ilg.Else();
                    doEndIf = true;
                }
                else {
                }

                WriteSourceBegin(source);
                if (element.Mapping.TypeDesc == QnameTypeDesc) {
                    MethodInfo XmlSerializationReader_ReadElementQualifiedName = typeof(XmlSerializationReader).GetMethod(
                           "ReadElementQualifiedName",
                           CodeGenerator.InstanceBindingFlags,
                           null,
                           CodeGenerator.EmptyTypeArray,
                           null
                           );
                    ilg.Ldarg(0);
                    ilg.Call(XmlSerializationReader_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, element.Mapping.TypeDesc.Type);
                if (doEndIf)
                    ilg.EndIf();
            }
            else if (element.Mapping is StructMapping) {
                TypeMapping mapping = element.Mapping;
                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(Res.GetString(Res.XmlInternalErrorMethod, mapping.TypeDesc.Name));
#endif

                if (checkForNull) {
                    MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod(
                        "get_Reader",
                        CodeGenerator.InstanceBindingFlags,
                        null,
                        CodeGenerator.EmptyTypeArray,
                        null
                        );
                    MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod(
                        "Skip",
                        CodeGenerator.InstanceBindingFlags,
                        null,
                        CodeGenerator.EmptyTypeArray,
                        null
                        );
                    ilg.Ldloc(arrayName);
                    ilg.Load(null);
                    ilg.If(Cmp.EqualTo);
                    ilg.Ldarg(0);
                    ilg.Call(XmlSerializationReader_get_Reader);
                    ilg.Call(XmlReader_Skip);
                    ilg.Else();
                }
                WriteSourceBegin(source);
                List<Type> argTypes = new List<Type>();
                ilg.Ldarg(0);
                if (mapping.TypeDesc.IsNullable) {
                    ilg.Load(element.IsNullable);
                    argTypes.Add(typeof(Boolean));
                }
                ilg.Ldc(true);
                argTypes.Add(typeof(Boolean));
                MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder,
                    methodName,
                    CodeGenerator.PrivateMethodAttributes,
                    mapping.TypeDesc.Type,
                    argTypes.ToArray()
                    );
                ilg.Call(methodBuilder);
                WriteSourceEnd(source, mapping.TypeDesc.Type);
                if (checkForNull)
                    // 'If' begins in checkForNull above
                    ilg.EndIf();
            }
            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);
                        MethodInfo XmlSerializationReader_ReadXmlXXX = typeof(XmlSerializationReader).GetMethod(
                              isDoc ? "ReadXmlDocument" : "ReadXmlNode",
                              CodeGenerator.InstanceBindingFlags,
                              null,
                              new Type[] { typeof(Boolean) },
                              null
                              );
                        ilg.Ldarg(0);
                        ilg.Ldc(element.Any ? false : true);
                        ilg.Call(XmlSerializationReader_ReadXmlXXX);
                        // See logic in WriteSourceBeginTyped whether or not to castclass.
                        if (special.TypeDesc != null)
                            ilg.Castclass(special.TypeDesc.Type);
                        WriteSourceEnd(source, special.TypeDesc.Type);
                        break;
                    case TypeKind.Serializable:
                        SerializableMapping sm = (SerializableMapping)element.Mapping;
                        // check to see if we need to do the derivation
                        if (sm.DerivedMappings != null) {
                            MethodInfo XmlSerializationReader_GetXsiType = typeof(XmlSerializationReader).GetMethod(
                                "GetXsiType",
                                CodeGenerator.InstanceBindingFlags,
                                null,
                                CodeGenerator.EmptyTypeArray,
                                null
                                );
                            Label labelTrue = ilg.DefineLabel();
                            Label labelEnd = ilg.DefineLabel();
                            LocalBuilder tserLoc = ilg.DeclareOrGetLocal(typeof(XmlQualifiedName), "tser");
                            ilg.Ldarg(0);
                            ilg.Call(XmlSerializationReader_GetXsiType);
                            ilg.Stloc(tserLoc);
                            ilg.Ldloc(tserLoc);
                            ilg.Load(null);
                            ilg.Ceq();
                            ilg.Brtrue(labelTrue);
                            WriteQNameEqual("tser", sm.XsiType.Name, sm.XsiType.Namespace);

                            ilg.Br_S(labelEnd);
                            ilg.MarkLabel(labelTrue);
                            ilg.Ldc(true);
                            ilg.MarkLabel(labelEnd);
                            ilg.If();
                        }
                        WriteSourceBeginTyped(source, sm.TypeDesc);
                        bool isWrappedAny = !element.Any && IsWildcard(sm);
                        MethodInfo XmlSerializationReader_ReadSerializable = typeof(XmlSerializationReader).GetMethod(
                             "ReadSerializable",
                             CodeGenerator.InstanceBindingFlags,
                             null,
                             isWrappedAny ? new Type[] { typeof(IXmlSerializable), typeof(Boolean) } : new Type[] { typeof(IXmlSerializable) },
                             null
                             );
                        ilg.Ldarg(0);
                        RaCodeGen.ILGenForCreateInstance(ilg, sm.TypeDesc.Type, sm.TypeDesc.CannotNew, false);
                        if (sm.TypeDesc.CannotNew)
                            ilg.ConvertValue(typeof(object), typeof(IXmlSerializable));
                        if (isWrappedAny)
                            ilg.Ldc(true);
                        ilg.Call(XmlSerializationReader_ReadSerializable);
                        // See logic in WriteSourceBeginTyped whether or not to castclass.
                        if (sm.TypeDesc != null)
                            ilg.ConvertValue(typeof(IXmlSerializable), sm.TypeDesc.Type);
                        WriteSourceEnd(source, sm.TypeDesc.Type);
                        if (sm.DerivedMappings != null) {
                            WriteDerivedSerializable(sm, sm, source, isWrappedAny);
                            WriteUnknownNode("UnknownNode", "null", null, true);
                        }
                        break;
                    default:
                        throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
                }
            }
            else {
                throw new InvalidOperationException(Res.GetString(Res.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(Res.GetString(Res.XmlInternalErrorDetails, "need parent for the " + source));
#endif

                WriteSourceBegin(choiceSource);
                CodeIdentifier.CheckValidIdentifier(choice.MemberIds[elementIndex]);
                RaCodeGen.ILGenForEnumMember(ilg, choice.Mapping.TypeDesc.Type, choice.MemberIds[elementIndex]);
                WriteSourceEnd(choiceSource, choice.Mapping.TypeDesc.Type);
            }
        }
Exemplo n.º 7
0
        private void WriteMemberElementsIf(ref object o, CollectionMember collectionMember, out Member member, Member[] expectedMembers, Member anyElementMember, UnknownNodeAction elementElseAction, object masterObject = null)
        {
            bool isSequence = IsSequence(expectedMembers);

            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.
            }

            ElementAccessor e = null;

            member = null;
            bool foundElement = false;

            foreach (var m in  expectedMembers)
            {
                if (m.Mapping.Xmlns != null)
                {
                    continue;
                }
                if (m.Mapping.Ignore)
                {
                    continue;
                }
                if (isSequence && (m.Mapping.IsText || m.Mapping.IsAttribute))
                {
                    continue;
                }

                foreach (var ele in m.Mapping.Elements)
                {
                    if (ele.Name == Reader.LocalName && ele.Namespace == Reader.NamespaceURI)
                    {
                        e            = ele;
                        member       = m;
                        foundElement = true;
                        break;
                    }
                }

                if (foundElement)
                {
                    break;
                }
            }

            if (foundElement)
            {
                ChoiceIdentifierAccessor choice = member.Mapping.ChoiceIdentifier;
                string ns     = e.Form == XmlSchemaForm.Qualified ? e.Namespace : "";
                bool   isList = member.Mapping.TypeDesc.IsArrayLike && !member.Mapping.TypeDesc.IsArray;
                WriteElement(ref o, collectionMember, e, choice, member.Mapping.CheckSpecified == SpecifiedAccessor.ReadWrite, isList && member.Mapping.TypeDesc.IsNullable, member.Mapping.ReadOnly, ns, masterObject);
            }
            else
            {
                if (anyElementMember != null && anyElementMember.Mapping != null)
                {
                    var anyElement = anyElementMember.Mapping;

                    member = anyElementMember;
                    ChoiceIdentifierAccessor choice   = member.Mapping.ChoiceIdentifier;
                    ElementAccessor[]        elements = anyElement.Elements;
                    for (int i = 0; i < elements.Length; i++)
                    {
                        ElementAccessor element = elements[i];
                        if (element.Any && element.Name.Length == 0)
                        {
                            string ns = element.Form == XmlSchemaForm.Qualified ? element.Namespace : "";
                            WriteElement(ref o, collectionMember, element, choice, anyElement.CheckSpecified == SpecifiedAccessor.ReadWrite, false, false, ns, masterObject: masterObject);
                            break;
                        }
                    }
                }
                else
                {
                    member = null;
                    ProcessUnknownNode(elementElseAction);
                }
            }
        }
Exemplo n.º 8
0
        void WriteChoiceTypeCheck(string source, string fullTypeName, ChoiceIdentifierAccessor choice, string enumName) {

            writer.Write("if (((object)");
            writer.Write(source);
            writer.Write(") != null && !(");
            writer.Write(source);
            writer.Write(" is ");
            writer.Write(fullTypeName);
            writer.Write(")) throw CreateMismatchChoiceException(");
            WriteQuotedCSharpString(fullTypeName);
            writer.Write(", ");
            WriteQuotedCSharpString(choice.MemberName);
            writer.Write(", ");
            WriteQuotedCSharpString(enumName);
            writer.WriteLine(");");
        }
        void WriteArrayItems(ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc, string arrayName, string choiceName)
        {
            TypeDesc arrayElementTypeDesc = arrayTypeDesc.ArrayElementTypeDesc;

            // The logic here is that
            // 1) Try to get the public "GetEnumerator" method. If the method exists, then use this method.
            // 2) If there's no public method exist, check if the type implemented IEnumerable<T>. If so, call the explicit method
            // 3) Otherwise, call the IEnumerable.GetEnumerator method
            if (arrayTypeDesc.IsEnumerable)
            {
                LocalBuilder eLoc = ilg.DeclareLocal(typeof(IEnumerator), "e");
                MethodInfo getEnumeratorMethod = arrayTypeDesc.Type.GetMethod(
                    "GetEnumerator",
                    CodeGenerator.InstancePublicBindingFlags,
                    null,
                    CodeGenerator.EmptyTypeArray,
                    null);


                if (getEnumeratorMethod != null && typeof(IEnumerator).IsAssignableFrom(getEnumeratorMethod.ReturnType))
                {
                    ilg.LoadAddress(ilg.GetVariable(arrayName));
                }
                else
                {
                    ilg.Load(ilg.GetVariable(arrayName));
                    Type typeIEnumerable = arrayTypeDesc.IsGenericInterface ? typeof(IEnumerable<>).MakeGenericType(arrayElementTypeDesc.Type) : typeof(IEnumerable);

                    getEnumeratorMethod = typeIEnumerable.GetMethod(
                        "GetEnumerator",
                        CodeGenerator.InstanceBindingFlags,
                        null,
                        CodeGenerator.EmptyTypeArray,
                        null);

                    ilg.ConvertValue(arrayTypeDesc.Type, typeIEnumerable);
                }

                ilg.Call(getEnumeratorMethod);
                ilg.ConvertValue(getEnumeratorMethod.ReturnType, typeof(IEnumerator));
                ilg.Stloc(eLoc);

                ilg.Ldloc(eLoc);
                ilg.Load(null);
                ilg.If(Cmp.NotEqualTo);
                ilg.WhileBegin();
                string arrayNamePlusA = (arrayName).Replace(arrayTypeDesc.Name, "") + "a" + arrayElementTypeDesc.Name;
                string arrayNamePlusI = (arrayName).Replace(arrayTypeDesc.Name, "") + "i" + arrayElementTypeDesc.Name;
                WriteLocalDecl(arrayNamePlusI, "e.Current", arrayElementTypeDesc.Type);
                WriteElements(new SourceInfo(arrayNamePlusI, null, null, arrayElementTypeDesc.Type, ilg), choiceName + "i", elements, text, choice, arrayNamePlusA, true, true);

                ilg.WhileBeginCondition(); // while (e.MoveNext())
                MethodInfo IEnumerator_MoveNext = typeof(IEnumerator).GetMethod(
                    "MoveNext",
                    CodeGenerator.InstanceBindingFlags,
                    null,
                    CodeGenerator.EmptyTypeArray,
                    null
                    );
                ilg.Ldloc(eLoc);
                ilg.Call(IEnumerator_MoveNext);
                ilg.WhileEndCondition();
                ilg.WhileEnd();

                ilg.EndIf(); // if (e != null)
            }
            else {
                // Filter out type specific for index (code match reusing local).
                string iPlusArrayName = "i" + (arrayName).Replace(arrayTypeDesc.Name, "");
                string arrayNamePlusA = (arrayName).Replace(arrayTypeDesc.Name, "") + "a" + arrayElementTypeDesc.Name;
                string arrayNamePlusI = (arrayName).Replace(arrayTypeDesc.Name, "") + "i" + arrayElementTypeDesc.Name;
                LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), iPlusArrayName);
                ilg.For(localI, 0, ilg.GetLocal(arrayName));
                int count = elements.Length + (text == null ? 0 : 1);
                if (count > 1) {
                    WriteLocalDecl(arrayNamePlusI, RaCodeGen.GetStringForArrayMember(arrayName, iPlusArrayName, arrayTypeDesc), arrayElementTypeDesc.Type);
                    if (choice != null) {
                        WriteLocalDecl(choiceName + "i", RaCodeGen.GetStringForArrayMember(choiceName, iPlusArrayName, choice.Mapping.TypeDesc), choice.Mapping.TypeDesc.Type);
                    }
                    WriteElements(new SourceInfo(arrayNamePlusI, null, null, arrayElementTypeDesc.Type, ilg), choiceName + "i", elements, text, choice, arrayNamePlusA, true, arrayElementTypeDesc.IsNullable);
                }
                else {
                    WriteElements(new SourceInfo(RaCodeGen.GetStringForArrayMember(arrayName, iPlusArrayName, arrayTypeDesc), null, null, arrayElementTypeDesc.Type, ilg), null, elements, text, choice, arrayNamePlusA, true, arrayElementTypeDesc.IsNullable);
                }
                ilg.EndFor();
            }
        }
Exemplo n.º 10
0
        void WriteArrayItems(ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc, string arrayName, string choiceName) {
            TypeDesc arrayElementTypeDesc = arrayTypeDesc.ArrayElementTypeDesc;

            if (arrayTypeDesc.IsEnumerable) {
                writer.Write(typeof(IEnumerator).FullName);
                writer.Write(" e = ");
                writer.Write(arrayName);
                writer.WriteLine(".GetEnumerator();");
                writer.WriteLine("if (e != null)");
                writer.WriteLine("while (e.MoveNext()) {");
                writer.Indent++;
                string arrayElementTypeName = CodeIdentifier.EscapeKeywords(arrayElementTypeDesc.FullName);
                writer.Write(arrayElementTypeName);
                writer.Write(" ");
                writer.Write(arrayName);
                writer.Write("i = (");
                writer.Write(arrayElementTypeName);
                writer.WriteLine(")e.Current;");
                WriteElements(arrayName + "i", choiceName + "i", elements, text, choice, arrayName + "a", true, true);
            }
            else {
                writer.Write("for (int i");
                writer.Write(arrayName);
                writer.Write(" = 0; i");
                writer.Write(arrayName);
                writer.Write(" < ");
                writer.Write(arrayName);
                writer.Write(".");
                writer.Write(arrayTypeDesc.ArrayLengthName);
                writer.Write("; i");
                writer.Write(arrayName);
                writer.WriteLine("++) {");
                writer.Indent++;
                int count = elements.Length + (text == null ? 0 : 1);
                if (count > 1) {
                    writer.Write(CodeIdentifier.EscapeKeywords(arrayElementTypeDesc.FullName));
                    writer.Write(" ");
                    writer.Write(arrayName);
                    writer.Write("i = ");
                    writer.Write(arrayName);
                    writer.Write("[i");
                    writer.Write(arrayName);
                    writer.WriteLine("];");
                    if (choice != null) {
                        writer.Write(CodeIdentifier.EscapeKeywords(choice.Mapping.TypeDesc.FullName));
                        writer.Write(" ");
                        writer.Write(choiceName);
                        writer.Write("i = ");
                        writer.Write(choiceName);
                        writer.Write("[i");
                        writer.Write(arrayName);
                        writer.WriteLine("];");
                    }
                    WriteElements(arrayName + "i", choiceName + "i", elements, text, choice, arrayName + "a", true, arrayElementTypeDesc.IsNullable);
                }
                else {
                    WriteElements(arrayName + "[i" + arrayName + "]", elements, text, choice, arrayName + "a", true, arrayElementTypeDesc.IsNullable);
                }
            }
            writer.Indent--;
            writer.WriteLine("}");
        }
Exemplo n.º 11
0
        void WriteElements(string source, string enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable) {
            if (elements.Length == 0 && text == null) return;
            if (elements.Length == 1 && text == null) {
                WriteElement("((" + CodeIdentifier.EscapeKeywords(((TypeMapping)elements[0].Mapping).TypeDesc.FullName) + ")" + source + ")", elements[0], arrayName, writeAccessors);
            }
            else {
                writer.WriteLine("{");
                writer.Indent++;
                int anyCount = 0;
                ArrayList namedAnys = new ArrayList();
                ElementAccessor unnamedAny = null; // can only have one
                bool wroteFirstIf = false;
                for (int i = 0; i < elements.Length; i++) {
                    ElementAccessor element = elements[i];
                    if (choice != null) {
                        string fullTypeName = CodeIdentifier.EscapeKeywords(((TypeMapping)element.Mapping).TypeDesc.FullName);
                        string enumTypeName = CodeIdentifier.EscapeKeywords(choice.Mapping.TypeDesc.FullName);
                        string enumFullName = enumTypeName + ".@";

                        string enumValue = null;
                        EnumMapping choiceMapping = (EnumMapping)choice.Mapping;
                        for (int j = 0; j < choiceMapping.Constants.Length; j++) {
                            string xmlName = choiceMapping.Constants[j].XmlName;
                            int colon = xmlName.LastIndexOf(':');
                            string choiceNs = colon < 0 ? element.Namespace : xmlName.Substring(0, colon);
                            string choiceName = colon < 0 ? xmlName : xmlName.Substring(colon+1);
                            if (element.Name == choiceName && element.Namespace == choiceNs) {
                                enumValue = choiceMapping.Constants[j].Name;
                                break;
                            }
                        }
                        if (enumValue == null || enumValue.Length == 0) {
                            // Type {0} is missing value for '{1}'.
                            throw new InvalidOperationException(Res.GetString(Res.XmlChoiceMissingValue, choiceMapping.TypeDesc.FullName, element.Name));
                        }
                        enumFullName += enumValue;

                        if (wroteFirstIf) writer.Write("else ");
                        else wroteFirstIf = true;
                        writer.Write("if (");
                        writer.Write(enumSource);
                        writer.Write(" == ");
                        writer.Write(enumFullName);
                        writer.WriteLine(") {");
                        writer.Indent++;

                        WriteChoiceTypeCheck(source, fullTypeName, choice, enumFullName);

                        WriteElement("((" + fullTypeName + ")" + source + ")", element, arrayName, writeAccessors);
                        writer.Indent--;
                        writer.WriteLine("}");
                    }
                    else if (element.Any) {
                        anyCount++;
                        if (element.Name != null && element.Name.Length > 0)
                            namedAnys.Add(element);
                        else if (unnamedAny == null)
                            unnamedAny = element;
                    }
                    else {
                        string fullTypeName = CodeIdentifier.EscapeKeywords(((TypeMapping)element.Mapping).TypeDesc.FullName);
                        if (wroteFirstIf) writer.Write("else ");
                        else wroteFirstIf = true;
                        writer.Write("if (");
                        writer.Write(source);
                        writer.Write(" is ");
                        writer.Write(fullTypeName);
                        writer.WriteLine(") {");
                        writer.Indent++;
                        WriteElement("((" + fullTypeName + ")" + source + ")", element, arrayName, writeAccessors);
                        writer.Indent--;
                        writer.WriteLine("}");
                    }
                }
                if (anyCount > 0) {
                    if (elements.Length - anyCount > 0) writer.Write("else ");
                    
                    string fullTypeName = typeof(XmlElement).FullName;

                    writer.Write("if (");
                    writer.Write(source);
                    writer.Write(" is ");
                    writer.Write(fullTypeName);
                    writer.WriteLine(") {");
                    writer.Indent++;

                    writer.Write(fullTypeName);
                    writer.Write(" elem = (");
                    writer.Write(fullTypeName);
                    writer.Write(")");
                    writer.Write(source);
                    writer.WriteLine(";");
                    
                    int c = 0;
                    foreach (ElementAccessor element in namedAnys) {
                        if (c++ > 0) writer.Write("else ");
                        writer.Write("if (elem.Name == ");
                        WriteQuotedCSharpString(element.Name);
                        writer.Write(" && elem.NamespaceURI == ");
                        WriteQuotedCSharpString(element.Namespace);
                        writer.WriteLine(") {");
                        writer.Indent++;
                        WriteElement("elem", element, arrayName, writeAccessors);
                        writer.Indent--;
                        writer.WriteLine("}");
                    }
                    if (c > 0) {
                        writer.WriteLine("else {");
                        writer.Indent++;
                    }
                    if (unnamedAny != null) {
                        WriteElement("elem", unnamedAny, arrayName, writeAccessors);
                    }
                    else {
                        writer.WriteLine("throw CreateUnknownAnyElementException(elem.Name, elem.NamespaceURI);");
                    }
                    if (c > 0) {
                        writer.Indent--;
                        writer.WriteLine("}");
                    }
                    writer.Indent--;
                    writer.WriteLine("}");
                }
                if (text != null) {
                    string fullTypeName = CodeIdentifier.EscapeKeywords(text.Mapping.TypeDesc.FullName);
                    if (elements.Length > 0) {
                        writer.Write("else ");
                        writer.Write("if (");
                        writer.Write(source);
                        writer.Write(" is ");
                        writer.Write(fullTypeName);
                        writer.WriteLine(") {");
                        writer.Indent++;
                        WriteText("((" + fullTypeName + ")" + source + ")", text);
                        writer.Indent--;
                        writer.WriteLine("}");
                    }
                    else {
                        WriteText("((" + fullTypeName + ")" + source + ")", text);
                    }
                }
                if (elements.Length > 0) {
                    writer.WriteLine("else {");

                    writer.Indent++;
                    if (isNullable) {
                        writer.Write("if (");
                        writer.Write(source);
                        writer.WriteLine(" != null) {");
                        writer.Indent++;
                    }
                    writer.Write("throw CreateUnknownTypeException(");
                    writer.Write(source);
                    writer.WriteLine(");");
                    if (isNullable) {
                        writer.Indent--;
                        writer.WriteLine("}");
                    }
                    writer.Indent--;
                    writer.WriteLine("}");
                }
                writer.Indent--;
                writer.WriteLine("}");
            }
        }
Exemplo n.º 12
0
        void WriteArray(string source, string choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc) {
            if (elements.Length == 0 && text == null) return;
            writer.WriteLine("{");
            writer.Indent++;
            string arrayTypeName = CodeIdentifier.EscapeKeywords(arrayTypeDesc.FullName);
            writer.Write(arrayTypeName);
            writer.Write(" a = (");
            writer.Write(arrayTypeName);
            writer.Write(")");
            writer.Write(source);
            writer.WriteLine(";");
            if (arrayTypeDesc.IsNullable) {
                writer.WriteLine("if (a != null) {");
                writer.Indent++;
            }

            if (choice != null) {
                writer.Write(CodeIdentifier.EscapeKeywords(choice.Mapping.TypeDesc.FullName));
                writer.Write("[] c = ");
                writer.Write(choiceSource);
                writer.WriteLine(";");
            }

            WriteArrayItems(elements, text, choice, arrayTypeDesc, "a", "c");
            if (arrayTypeDesc.IsNullable) {
                writer.Indent--;
                writer.WriteLine("}");
            }
            writer.Indent--;
            writer.WriteLine("}");
        }
 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))
     {
         base.Writer.Write(checkSpecified);
         base.Writer.WriteLine(" = true;");
     }
     if (element.Mapping is ArrayMapping)
     {
         this.WriteArray(source, arrayName, (ArrayMapping) element.Mapping, readOnly, element.IsNullable, fixupIndex);
     }
     else if (element.Mapping is NullableMapping)
     {
         string s = base.ReferenceMapping(element.Mapping);
         this.WriteSourceBegin(source);
         base.Writer.Write(s);
         base.Writer.Write("(true)");
         this.WriteSourceEnd(source);
         base.Writer.WriteLine(";");
     }
     else if (!element.Mapping.IsSoap && (element.Mapping is PrimitiveMapping))
     {
         if (element.IsNullable)
         {
             base.Writer.WriteLine("if (ReadNull()) {");
             IndentedWriter writer1 = base.Writer;
             writer1.Indent++;
             this.WriteSourceBegin(source);
             if (element.Mapping.TypeDesc.IsValueType)
             {
                 base.Writer.Write(base.RaCodeGen.GetStringForCreateInstance(element.Mapping.TypeDesc.CSharpName, element.Mapping.TypeDesc.UseReflection, false, false));
             }
             else
             {
                 base.Writer.Write("null");
             }
             this.WriteSourceEnd(source);
             base.Writer.WriteLine(";");
             IndentedWriter writer2 = base.Writer;
             writer2.Indent--;
             base.Writer.WriteLine("}");
             base.Writer.Write("else ");
         }
         if (((element.Default != null) && (element.Default != DBNull.Value)) && element.Mapping.TypeDesc.IsValueType)
         {
             base.Writer.WriteLine("if (Reader.IsEmptyElement) {");
             IndentedWriter writer3 = base.Writer;
             writer3.Indent++;
             base.Writer.WriteLine("Reader.Skip();");
             IndentedWriter writer4 = base.Writer;
             writer4.Indent--;
             base.Writer.WriteLine("}");
             base.Writer.WriteLine("else {");
         }
         else
         {
             base.Writer.WriteLine("{");
         }
         IndentedWriter writer = base.Writer;
         writer.Indent++;
         this.WriteSourceBegin(source);
         if (element.Mapping.TypeDesc == base.QnameTypeDesc)
         {
             base.Writer.Write("ReadElementQualifiedName()");
         }
         else
         {
             string str2;
             string str5;
             if (((str5 = element.Mapping.TypeDesc.FormatterName) != null) && ((str5 == "ByteArrayBase64") || (str5 == "ByteArrayHex")))
             {
                 str2 = "false";
             }
             else
             {
                 str2 = "Reader.ReadElementString()";
             }
             this.WritePrimitive(element.Mapping, str2);
         }
         this.WriteSourceEnd(source);
         base.Writer.WriteLine(";");
         IndentedWriter writer6 = base.Writer;
         writer6.Indent--;
         base.Writer.WriteLine("}");
     }
     else if ((element.Mapping is StructMapping) || (element.Mapping.IsSoap && (element.Mapping is PrimitiveMapping)))
     {
         TypeMapping mapping = element.Mapping;
         if (mapping.IsSoap)
         {
             base.Writer.Write("object rre = ");
             base.Writer.Write((fixupIndex >= 0) ? "ReadReferencingElement" : "ReadReferencedElement");
             base.Writer.Write("(");
             this.WriteID(mapping.TypeName);
             base.Writer.Write(", ");
             this.WriteID(mapping.Namespace);
             if (fixupIndex >= 0)
             {
                 base.Writer.Write(", out fixup.Ids[");
                 base.Writer.Write(fixupIndex.ToString(CultureInfo.InvariantCulture));
                 base.Writer.Write("]");
             }
             base.Writer.Write(")");
             this.WriteSourceEnd(source);
             base.Writer.WriteLine(";");
             if (mapping.TypeDesc.IsValueType)
             {
                 base.Writer.WriteLine("if (rre != null) {");
                 IndentedWriter writer7 = base.Writer;
                 writer7.Indent++;
             }
             base.Writer.WriteLine("try {");
             IndentedWriter writer8 = base.Writer;
             writer8.Indent++;
             this.WriteSourceBeginTyped(source, mapping.TypeDesc);
             base.Writer.Write("rre");
             this.WriteSourceEnd(source);
             base.Writer.WriteLine(";");
             this.WriteCatchCastException(mapping.TypeDesc, "rre", null);
             base.Writer.Write("Referenced(");
             base.Writer.Write(source);
             base.Writer.WriteLine(");");
             if (mapping.TypeDesc.IsValueType)
             {
                 IndentedWriter writer9 = base.Writer;
                 writer9.Indent--;
                 base.Writer.WriteLine("}");
             }
         }
         else
         {
             string str3 = base.ReferenceMapping(mapping);
             if (checkForNull)
             {
                 base.Writer.Write("if ((object)(");
                 base.Writer.Write(arrayName);
                 base.Writer.Write(") == null) Reader.Skip(); else ");
             }
             this.WriteSourceBegin(source);
             base.Writer.Write(str3);
             base.Writer.Write("(");
             if (mapping.TypeDesc.IsNullable)
             {
                 this.WriteBooleanValue(element.IsNullable);
                 base.Writer.Write(", ");
             }
             base.Writer.Write("true");
             base.Writer.Write(")");
             this.WriteSourceEnd(source);
             base.Writer.WriteLine(";");
         }
     }
     else
     {
         if (!(element.Mapping is SpecialMapping))
         {
             throw new InvalidOperationException(Res.GetString("XmlInternalError"));
         }
         SpecialMapping mapping2 = (SpecialMapping) element.Mapping;
         switch (mapping2.TypeDesc.Kind)
         {
             case TypeKind.Node:
             {
                 bool flag = mapping2.TypeDesc.FullName == typeof(XmlDocument).FullName;
                 this.WriteSourceBeginTyped(source, mapping2.TypeDesc);
                 base.Writer.Write(flag ? "ReadXmlDocument(" : "ReadXmlNode(");
                 base.Writer.Write(element.Any ? "false" : "true");
                 base.Writer.Write(")");
                 this.WriteSourceEnd(source);
                 base.Writer.WriteLine(";");
                 goto Label_08BC;
             }
             case TypeKind.Serializable:
             {
                 SerializableMapping mapping3 = (SerializableMapping) element.Mapping;
                 if (mapping3.DerivedMappings != null)
                 {
                     base.Writer.Write(typeof(XmlQualifiedName).FullName);
                     base.Writer.WriteLine(" tser = GetXsiType();");
                     base.Writer.Write("if (tser == null");
                     base.Writer.Write(" || ");
                     this.WriteQNameEqual("tser", mapping3.XsiType.Name, mapping3.XsiType.Namespace);
                     base.Writer.WriteLine(") {");
                     IndentedWriter writer10 = base.Writer;
                     writer10.Indent++;
                 }
                 this.WriteSourceBeginTyped(source, mapping3.TypeDesc);
                 base.Writer.Write("ReadSerializable(( ");
                 base.Writer.Write(typeof(IXmlSerializable).FullName);
                 base.Writer.Write(")");
                 base.Writer.Write(base.RaCodeGen.GetStringForCreateInstance(mapping3.TypeDesc.CSharpName, mapping3.TypeDesc.UseReflection, mapping3.TypeDesc.CannotNew, false));
                 bool isWrappedAny = !element.Any && XmlSerializationCodeGen.IsWildcard(mapping3);
                 if (isWrappedAny)
                 {
                     base.Writer.WriteLine(", true");
                 }
                 base.Writer.Write(")");
                 this.WriteSourceEnd(source);
                 base.Writer.WriteLine(";");
                 if (mapping3.DerivedMappings != null)
                 {
                     IndentedWriter writer11 = base.Writer;
                     writer11.Indent--;
                     base.Writer.WriteLine("}");
                     this.WriteDerivedSerializable(mapping3, mapping3, source, isWrappedAny);
                     this.WriteUnknownNode("UnknownNode", "null", null, true);
                 }
                 goto Label_08BC;
             }
         }
         throw new InvalidOperationException(Res.GetString("XmlInternalError"));
     }
 Label_08BC:
     if (choice != null)
     {
         string cSharpName = choice.Mapping.TypeDesc.CSharpName;
         base.Writer.Write(choiceSource);
         base.Writer.Write(" = ");
         CodeIdentifier.CheckValidIdentifier(choice.MemberIds[elementIndex]);
         base.Writer.Write(base.RaCodeGen.GetStringForEnumMember(cSharpName, choice.MemberIds[elementIndex], choice.Mapping.TypeDesc.UseReflection));
         base.Writer.WriteLine(";");
     }
 }
 private void WriteArrayItems(ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc, string arrayName, string choiceName)
 {
     TypeDesc arrayElementTypeDesc = arrayTypeDesc.ArrayElementTypeDesc;
     if (arrayTypeDesc.IsEnumerable)
     {
         base.Writer.Write(typeof(IEnumerator).FullName);
         base.Writer.Write(" e = ");
         if (arrayTypeDesc.IsPrivateImplementation)
         {
             base.Writer.Write("((");
             base.Writer.Write(typeof(IEnumerable).FullName);
             base.Writer.Write(")");
             base.Writer.Write(arrayName);
             base.Writer.WriteLine(").GetEnumerator();");
         }
         else if (arrayTypeDesc.IsGenericInterface)
         {
             if (arrayTypeDesc.UseReflection)
             {
                 base.Writer.Write("(");
                 base.Writer.Write(typeof(IEnumerator).FullName);
                 base.Writer.Write(")");
                 base.Writer.Write(base.RaCodeGen.GetReflectionVariable(arrayTypeDesc.CSharpName, "System.Collections.Generic.IEnumerable*"));
                 base.Writer.Write(".Invoke(");
                 base.Writer.Write(arrayName);
                 base.Writer.WriteLine(", new object[0]);");
             }
             else
             {
                 base.Writer.Write("((System.Collections.Generic.IEnumerable<");
                 base.Writer.Write(arrayElementTypeDesc.CSharpName);
                 base.Writer.Write(">)");
                 base.Writer.Write(arrayName);
                 base.Writer.WriteLine(").GetEnumerator();");
             }
         }
         else
         {
             if (arrayTypeDesc.UseReflection)
             {
                 base.Writer.Write("(");
                 base.Writer.Write(typeof(IEnumerator).FullName);
                 base.Writer.Write(")");
             }
             base.Writer.Write(base.RaCodeGen.GetStringForMethodInvoke(arrayName, arrayTypeDesc.CSharpName, "GetEnumerator", arrayTypeDesc.UseReflection, new string[0]));
             base.Writer.WriteLine(";");
         }
         base.Writer.WriteLine("if (e != null)");
         base.Writer.WriteLine("while (e.MoveNext()) {");
         IndentedWriter writer1 = base.Writer;
         writer1.Indent++;
         string cSharpName = arrayElementTypeDesc.CSharpName;
         this.WriteLocalDecl(cSharpName, arrayName + "i", "e.Current", arrayElementTypeDesc.UseReflection);
         this.WriteElements(arrayName + "i", choiceName + "i", elements, text, choice, arrayName + "a", true, true);
     }
     else
     {
         base.Writer.Write("for (int i");
         base.Writer.Write(arrayName);
         base.Writer.Write(" = 0; i");
         base.Writer.Write(arrayName);
         base.Writer.Write(" < ");
         if (arrayTypeDesc.IsArray)
         {
             base.Writer.Write(arrayName);
             base.Writer.Write(".Length");
         }
         else
         {
             base.Writer.Write("((");
             base.Writer.Write(typeof(ICollection).FullName);
             base.Writer.Write(")");
             base.Writer.Write(arrayName);
             base.Writer.Write(").Count");
         }
         base.Writer.Write("; i");
         base.Writer.Write(arrayName);
         base.Writer.WriteLine("++) {");
         IndentedWriter writer2 = base.Writer;
         writer2.Indent++;
         int num = elements.Length + ((text == null) ? 0 : 1);
         if (num > 1)
         {
             string typeName = arrayElementTypeDesc.CSharpName;
             this.WriteLocalDecl(typeName, arrayName + "i", base.RaCodeGen.GetStringForArrayMember(arrayName, "i" + arrayName, arrayTypeDesc), arrayElementTypeDesc.UseReflection);
             if (choice != null)
             {
                 string str3 = choice.Mapping.TypeDesc.CSharpName;
                 this.WriteLocalDecl(str3, choiceName + "i", base.RaCodeGen.GetStringForArrayMember(choiceName, "i" + arrayName, choice.Mapping.TypeDesc), choice.Mapping.TypeDesc.UseReflection);
             }
             this.WriteElements(arrayName + "i", choiceName + "i", elements, text, choice, arrayName + "a", true, arrayElementTypeDesc.IsNullable);
         }
         else
         {
             this.WriteElements(base.RaCodeGen.GetStringForArrayMember(arrayName, "i" + arrayName, arrayTypeDesc), elements, text, choice, arrayName + "a", true, arrayElementTypeDesc.IsNullable);
         }
     }
     IndentedWriter writer = base.Writer;
     writer.Indent--;
     base.Writer.WriteLine("}");
 }
Exemplo n.º 15
0
        void WriteElements(string source, string enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable) {
            if (elements.Length == 0 && text == null) return;
            if (elements.Length == 1 && text == null) {
                TypeDesc td = elements[0].IsUnbounded ? elements[0].Mapping.TypeDesc.CreateArrayTypeDesc() : elements[0].Mapping.TypeDesc;
                if (!elements[0].Any && !elements[0].Mapping.TypeDesc.UseReflection && !elements[0].Mapping.TypeDesc.IsOptionalValue)
                    source = "(("+td.CSharpName+")"+ source+")";
                WriteElement(source, elements[0], arrayName, writeAccessors);
            }
            else {
                if (isNullable && choice == null) {
                    Writer.Write("if ((object)(");
                    Writer.Write(source);
                    Writer.Write(") != null)");
                }
                Writer.WriteLine("{");
                Writer.Indent++;
                int anyCount = 0;
                ArrayList namedAnys = new ArrayList();
                ElementAccessor unnamedAny = null; // can only have one
                bool wroteFirstIf = false;
                string enumTypeName = choice == null ? null : choice.Mapping.TypeDesc.FullName;

                for (int i = 0; i < elements.Length; i++) {
                    ElementAccessor element = elements[i];

                    if (element.Any) {
                        anyCount++;
                        if (element.Name != null && element.Name.Length > 0)
                            namedAnys.Add(element);
                        else if (unnamedAny == null)
                            unnamedAny = element;
                    }
                    else if (choice != null) {
                        bool useReflection = element.Mapping.TypeDesc.UseReflection;
                        string fullTypeName = element.Mapping.TypeDesc.CSharpName;
                        bool enumUseReflection = choice.Mapping.TypeDesc.UseReflection;
                        string enumFullName = (enumUseReflection?"":enumTypeName + ".@") + FindChoiceEnumValue(element, (EnumMapping)choice.Mapping, enumUseReflection);

                        if (wroteFirstIf) Writer.Write("else ");
                        else wroteFirstIf = true;
                        Writer.Write("if (");
                        Writer.Write(enumUseReflection?RaCodeGen.GetStringForEnumLongValue(enumSource, enumUseReflection):enumSource);
                        Writer.Write(" == ");
                        Writer.Write(enumFullName);
                        if (isNullable && !element.IsNullable) {
                            Writer.Write(" && ((object)(");
                            Writer.Write(source);
                            Writer.Write(") != null)");
                        }
                        Writer.WriteLine(") {");
                        Writer.Indent++;

                        WriteChoiceTypeCheck(source, fullTypeName, useReflection, choice, enumFullName, element.Mapping.TypeDesc);

                        string castedSource = source;
                        if (!useReflection)
                            castedSource = "(("+fullTypeName+")"+ source+")";
                        WriteElement(element.Any ? source : castedSource, element, arrayName, writeAccessors);
                        Writer.Indent--;
                        Writer.WriteLine("}");
                    }
                    else {
                        bool useReflection = element.Mapping.TypeDesc.UseReflection;
                        TypeDesc td = element.IsUnbounded ? element.Mapping.TypeDesc.CreateArrayTypeDesc() : element.Mapping.TypeDesc;
                        string fullTypeName = td.CSharpName;
                        if (wroteFirstIf) Writer.Write("else ");
                        else wroteFirstIf = true;
                        Writer.Write("if (");
                        WriteInstanceOf(source, fullTypeName, useReflection);
                        Writer.WriteLine(") {");
                        Writer.Indent++;
                        string castedSource = source;
                        if (!useReflection)
                            castedSource = "(("+fullTypeName+")"+ source+")";
                        WriteElement(element.Any ? source : castedSource, element, arrayName, writeAccessors);
                        Writer.Indent--;
                        Writer.WriteLine("}");
                    }
                }
                if (anyCount > 0) {
                    if (elements.Length - anyCount > 0) Writer.Write("else ");
                    
                    string fullTypeName = typeof(XmlElement).FullName;

                    Writer.Write("if (");
                    Writer.Write(source);
                    Writer.Write(" is ");
                    Writer.Write(fullTypeName);
                    Writer.WriteLine(") {");
                    Writer.Indent++;

                    Writer.Write(fullTypeName);
                    Writer.Write(" elem = (");
                    Writer.Write(fullTypeName);
                    Writer.Write(")");
                    Writer.Write(source);
                    Writer.WriteLine(";");
                    
                    int c = 0;

                    foreach (ElementAccessor element in namedAnys) {
                        if (c++ > 0) Writer.Write("else ");

                        string enumFullName = null;

                        bool useReflection = element.Mapping.TypeDesc.UseReflection;
                        if (choice != null) {
                            bool enumUseReflection = choice.Mapping.TypeDesc.UseReflection;
                            enumFullName = (enumUseReflection?"":enumTypeName + ".@") + FindChoiceEnumValue(element, (EnumMapping)choice.Mapping, enumUseReflection);
                            Writer.Write("if (");
                            Writer.Write(enumUseReflection?RaCodeGen.GetStringForEnumLongValue(enumSource, enumUseReflection):enumSource);
                            Writer.Write(" == ");
                            Writer.Write(enumFullName);
                            if (isNullable && !element.IsNullable) {
                                Writer.Write(" && ((object)(");
                                Writer.Write(source);
                                Writer.Write(") != null)");
                            }
                            Writer.WriteLine(") {");
                            Writer.Indent++;
                        }
                        Writer.Write("if (elem.Name == ");
                        WriteQuotedCSharpString(element.Name);
                        Writer.Write(" && elem.NamespaceURI == ");
                        WriteQuotedCSharpString(element.Namespace);
                        Writer.WriteLine(") {");
                        Writer.Indent++;
                        WriteElement("elem", element, arrayName, writeAccessors);

                        if (choice != null) {
                            Writer.Indent--;
                            Writer.WriteLine("}");
                            Writer.WriteLine("else {");
                            Writer.Indent++;

                            Writer.WriteLine("// throw Value '{0}' of the choice identifier '{1}' does not match element '{2}' from namespace '{3}'.");
                            
                            Writer.Write("throw CreateChoiceIdentifierValueException(");
                            WriteQuotedCSharpString(enumFullName);
                            Writer.Write(", ");
                            WriteQuotedCSharpString(choice.MemberName);
                            Writer.WriteLine(", elem.Name, elem.NamespaceURI);");
                            Writer.Indent--;
                            Writer.WriteLine("}");
                        }
                        Writer.Indent--;
                        Writer.WriteLine("}");
                    }
                    if (c > 0) {
                        Writer.WriteLine("else {");
                        Writer.Indent++;
                    }
                    if (unnamedAny != null) {
                        WriteElement("elem", unnamedAny, arrayName, writeAccessors);
                    }
                    else {
                        Writer.WriteLine("throw CreateUnknownAnyElementException(elem.Name, elem.NamespaceURI);");
                    }
                    if (c > 0) {
                        Writer.Indent--;
                        Writer.WriteLine("}");
                    }
                    Writer.Indent--;
                    Writer.WriteLine("}");
                }
                if (text != null) {
                    bool useReflection = text.Mapping.TypeDesc.UseReflection;
                    string fullTypeName = text.Mapping.TypeDesc.CSharpName;
                    if (elements.Length > 0) {
                        Writer.Write("else ");
                        Writer.Write("if (");
                        WriteInstanceOf(source, fullTypeName, useReflection);
                        Writer.WriteLine(") {");
                        Writer.Indent++;
                        string castedSource = source;
                        if (!useReflection)
                            castedSource = "(("+fullTypeName+")"+ source+")";
                        WriteText(castedSource, text);
                        Writer.Indent--;
                        Writer.WriteLine("}");
                    }
                    else {
                        string castedSource = source;
                        if (!useReflection)
                            castedSource = "(("+fullTypeName+")"+ source+")";
                        WriteText(castedSource, text);
                    }
                }
                if (elements.Length > 0) {
                    Writer.Write("else ");

                    if (isNullable) {
                        Writer.Write(" if ((object)(");
                        Writer.Write(source);
                        Writer.Write(") != null)");
                    }

                    Writer.WriteLine("{");
                    Writer.Indent++;

                    Writer.Write("throw CreateUnknownTypeException(");
                    Writer.Write(source);
                    Writer.WriteLine(");");

                    Writer.Indent--;
                    Writer.WriteLine("}");
                }
                Writer.Indent--;
                Writer.WriteLine("}");
            }
        }
Exemplo n.º 16
0
        void WriteElement(string source, string arrayName, string choiceSource, ElementAccessor element, ChoiceIdentifierAccessor choice, string checkSpecified, bool checkForNull, bool readOnly, int fixupIndex, int elementIndex) {
            if (element.Mapping is ArrayMapping)
                WriteArray(source, arrayName, (ArrayMapping)element.Mapping, readOnly, element.IsNullable, fixupIndex);
            else if (!element.Mapping.IsSoap && (element.Mapping is PrimitiveMapping)) {
                WriteSourceBegin(source);
                if (element.Mapping.TypeDesc == qnameTypeDesc)
                    writer.Write(element.IsNullable || element.Mapping.IsSoap ? "ReadNullableQualifiedName()" : "ReadElementQualifiedName()");
                else {
                    string readFunc; 
                    switch(((TypeMapping)element.Mapping).TypeDesc.FormatterName) {
                    case "ByteArrayBase64":
                    case "ByteArrayHex":    readFunc = element.IsNullable || element.Mapping.IsSoap? "ReadNull()":"false";
                                            break;
                    default:                readFunc = element.IsNullable || element.Mapping.IsSoap ? "ReadNullableString()" : "Reader.ReadElementString()";
                                            break;
                    }
                    WritePrimitive((TypeMapping)element.Mapping, readFunc);
                }

                WriteSourceEnd(source);
                writer.WriteLine(";");
                if (checkSpecified != null && checkSpecified.Length > 0) {
                    CodeIdentifier.CheckValidIdentifier(checkSpecified);
                    writer.Write("o.");
                    writer.Write(checkSpecified);
                    writer.WriteLine("Specified = true;");
                }
            }
            else if (element.Mapping is StructMapping || (element.Mapping.IsSoap && element.Mapping is PrimitiveMapping)) {
                TypeMapping mapping = element.Mapping;
                if (mapping.IsSoap) {
                    writer.Write("object rre = ");

                    if (fixupIndex >= 0) {
                        writer.Write("ReadReferencingElement(");

                        WriteID(mapping.TypeName);
                        writer.Write(", ");
                        WriteID(mapping.Namespace);

                        writer.Write(", out fixup.Ids[");
                        writer.Write((fixupIndex).ToString());
                        writer.Write("]");
                    }
                    else
                        writer.Write("ReadReferencedElement(");
                    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.WriteLine("rre;");
                    WriteCatchCastException(mapping.TypeDesc, "rre");
                    writer.Write("Referenced(");
                    writer.Write(source);
                    writer.WriteLine(");");

                    if (mapping.TypeDesc.IsValueType) {
                        writer.Indent--;
                        writer.WriteLine("}");
                    }
                }
                else {

                    string methodName = (string)methodNames[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(Res.GetString(Res.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;
                WriteSourceBeginTyped(source, special.TypeDesc);
                switch (special.TypeDesc.Kind) {
                    case TypeKind.Node:
                        writer.Write("ReadXmlNode(");
                        writer.Write(element.Any ? "false" : "true");
                        writer.Write(")");
                        break;
                    case TypeKind.Serializable:
                        writer.Write("ReadSerializable(new ");
                        writer.Write(CodeIdentifier.EscapeKeywords(special.TypeDesc.FullName));
                        writer.Write("())");
                        break;
                    default:
                        throw new InvalidOperationException(Res.GetString(Res.XmlInternalError));
                }
                WriteSourceEnd(source);
                writer.WriteLine(";");
            }
            else {
                throw new InvalidOperationException(Res.GetString(Res.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(Res.GetString(Res.XmlInternalErrorDetails, "need parent for the " + source));
                #endif

                string enumTypeName = CodeIdentifier.EscapeKeywords(choice.Mapping.TypeDesc.FullName);
                writer.Write(choiceSource);
                writer.Write(" = ");
                writer.Write(enumTypeName);
                writer.Write(".@");
                CodeIdentifier.CheckValidIdentifier(choice.MemberIds[elementIndex]);
                writer.Write(choice.MemberIds[elementIndex]);
                writer.WriteLine(";");
            }
        }
 private void WriteArray(string source, string choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc)
 {
     if ((elements.Length != 0) || (text != null))
     {
         base.Writer.WriteLine("{");
         IndentedWriter writer = base.Writer;
         writer.Indent++;
         string cSharpName = arrayTypeDesc.CSharpName;
         this.WriteArrayLocalDecl(cSharpName, "a", source, arrayTypeDesc);
         if (arrayTypeDesc.IsNullable)
         {
             base.Writer.WriteLine("if (a != null) {");
             IndentedWriter writer2 = base.Writer;
             writer2.Indent++;
         }
         if (choice != null)
         {
             bool useReflection = choice.Mapping.TypeDesc.UseReflection;
             this.WriteArrayLocalDecl(choice.Mapping.TypeDesc.CSharpName + "[]", "c", choiceSource, choice.Mapping.TypeDesc);
             base.Writer.WriteLine("if (c == null || c.Length < a.Length) {");
             IndentedWriter writer3 = base.Writer;
             writer3.Indent++;
             base.Writer.Write("throw CreateInvalidChoiceIdentifierValueException(");
             base.WriteQuotedCSharpString(choice.Mapping.TypeDesc.FullName);
             base.Writer.Write(", ");
             base.WriteQuotedCSharpString(choice.MemberName);
             base.Writer.Write(");");
             IndentedWriter writer4 = base.Writer;
             writer4.Indent--;
             base.Writer.WriteLine("}");
         }
         this.WriteArrayItems(elements, text, choice, arrayTypeDesc, "a", "c");
         if (arrayTypeDesc.IsNullable)
         {
             IndentedWriter writer5 = base.Writer;
             writer5.Indent--;
             base.Writer.WriteLine("}");
         }
         IndentedWriter writer6 = base.Writer;
         writer6.Indent--;
         base.Writer.WriteLine("}");
     }
 }
Exemplo n.º 18
0
 private void WriteMember(object o, object choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc memberTypeDesc, bool writeAccessors, XmlMapping parentMapping = null)
 {
     if (memberTypeDesc.IsArrayLike &&
         !(elements.Length == 1 && elements[0].Mapping is ArrayMapping))
     {
         WriteArray(o, choiceSource, elements, text, choice, memberTypeDesc);
     }
     else
     {
         WriteElements(o, choiceSource, elements, text, choice, "a", writeAccessors, memberTypeDesc.IsNullable, parentMapping);
     }
 }
        private void WriteElement(ref object o, CollectionMember collectionMember, ElementAccessor element, ChoiceIdentifierAccessor choice, bool checkSpecified, bool checkForNull, bool readOnly, string defaultNamespace, object masterObject = null)
        {
            object value = null;

            if (element.Mapping is ArrayMapping)
            {
                WriteArray(ref value, (ArrayMapping)element.Mapping, readOnly, element.IsNullable, defaultNamespace);
            }
            else if (element.Mapping is NullableMapping)
            {
                value = WriteNullableMethod((NullableMapping)element.Mapping, true, defaultNamespace);
            }
            else if (!element.Mapping.IsSoap && (element.Mapping is PrimitiveMapping))
            {
                if (element.IsNullable && ReadNull())
                {
                    if (element.Mapping.TypeDesc.IsValueType)
                    {
                        value = ReflectionCreateObject(element.Mapping.TypeDesc.Type);
                    }
                    else
                    {
                        value = null;
                    }
                }
                else if ((element.Default != null && !Globals.IsDBNullValue(element.Default) && element.Mapping.TypeDesc.IsValueType) &&
                         (Reader.IsEmptyElement))
                {
                    Reader.Skip();
                }
                else
                {
                    if (element.Mapping.TypeDesc == QnameTypeDesc)
                    {
                        value = ReadElementQualifiedName();
                    }
                    else
                    {
                        if (element.Mapping.TypeDesc.FormatterName == "ByteArrayBase64")
                        {
                            value = ToByteArrayBase64(false);
                        }
                        else if (element.Mapping.TypeDesc.FormatterName == "ByteArrayHex")
                        {
                            value = ToByteArrayHex(false);
                        }
                        else
                        {
                            Func <string> readFunc = () => Reader.ReadElementContentAsString();

                            value = WritePrimitive(element.Mapping, readFunc);
                        }
                    }
                }
            }
            else if (element.Mapping is StructMapping || (element.Mapping.IsSoap && element.Mapping is PrimitiveMapping))
            {
                TypeMapping mapping = element.Mapping;
                if (mapping.IsSoap)
                {
                    throw new PlatformNotSupportedException();
                }
                else
                {
                    if (checkForNull && o == null)
                    {
                        Reader.Skip();
                    }
                    else
                    {
                        value = WriteStructMethod(
                            mapping: (StructMapping)mapping,
                            isNullable: mapping.TypeDesc.IsNullable && element.IsNullable,
                            checkType: true,
                            defaultNamespace: defaultNamespace
                            );
                    }
                }
            }
            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;
                    if (isDoc)
                    {
                        value = ReadXmlDocument(!element.Any);
                    }
                    else
                    {
                        value = ReadXmlNode(!element.Any);
                    }

                    break;

                case TypeKind.Serializable:
                    SerializableMapping sm = (SerializableMapping)element.Mapping;
                    // check to see if we need to do the derivation
                    bool flag = true;
                    if (sm.DerivedMappings != null)
                    {
                        XmlQualifiedName tser = GetXsiType();
                        if (tser == null || QNameEqual(tser, sm.XsiType.Name, sm.XsiType.Namespace, defaultNamespace))
                        {
                        }
                        else
                        {
                            flag = false;
                        }
                    }

                    if (flag)
                    {
                        bool isWrappedAny = !element.Any && IsWildcard(sm);
                        value = ReadSerializable((IXmlSerializable)ReflectionCreateObject(sm.TypeDesc.Type), isWrappedAny);
                    }

                    if (sm.DerivedMappings != null)
                    {
                        // #10587: To Support SpecialMapping Types Having DerivedMappings
                        throw new NotImplementedException("sm.DerivedMappings != null");
                        //WriteDerivedSerializable(sm, sm, source, isWrappedAny);
                        //WriteUnknownNode("UnknownNode", "null", null, true);
                    }
                    break;

                default:
                    throw new InvalidOperationException(SR.Format(SR.XmlInternalError));
                }
            }
            else
            {
                throw new InvalidOperationException(SR.Format(SR.XmlInternalError));
            }

            if (choice != null && masterObject != null)
            {
                foreach (var name in choice.MemberIds)
                {
                    if (name == element.Name)
                    {
                        object choiceValue = Enum.Parse(choice.Mapping.TypeDesc.Type, name);
                        SetOrAddValueToMember(masterObject, choiceValue, choice.MemberInfo);

                        break;
                    }
                }
            }

            if (collectionMember != null)
            {
                collectionMember.Add(value);
            }
            else
            {
                o = value;
            }
        }
Exemplo n.º 20
0
        private void WriteArray(object o, object choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc)
        {
            if (elements.Length == 0 && text == null)
            {
                return;
            }

            if (arrayTypeDesc.IsNullable && o == null)
            {
                return;
            }

            if (choice != null)
            {
                if (choiceSource == null || ((Array)choiceSource).Length < ((Array)o).Length)
                {
                    throw CreateInvalidChoiceIdentifierValueException(choice.Mapping.TypeDesc.FullName, choice.MemberName);
                }
            }

            WriteArrayItems(elements, text, choice, arrayTypeDesc, o);
        }
 private void WriteMember(object o, object choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc memberTypeDesc, bool writeAccessors, XmlMapping parentMapping = null)
 {
     if (memberTypeDesc.IsArrayLike &&
         !(elements.Length == 1 && elements[0].Mapping is ArrayMapping))
     {
         WriteArray(o, choiceSource, elements, text, choice, memberTypeDesc);
     }
     else
     {
         WriteElements(o, choiceSource, elements, text, choice, "a", writeAccessors, memberTypeDesc.IsNullable, parentMapping);
     }
 }
Exemplo n.º 22
0
        private void WriteElements(object o, object enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable, XmlMapping parentMapping = null)
        {
            if (elements.Length == 0 && text == null)
            {
                return;
            }
            if (elements.Length == 1 && text == null)
            {
                WriteElement(o, elements[0], arrayName, writeAccessors, parentMapping);
            }
            else
            {
                if (isNullable && choice == null && o == null)
                {
                    return;
                }

                int             anyCount     = 0;
                var             namedAnys    = new List <ElementAccessor>();
                ElementAccessor unnamedAny   = null; // can only have one
                string          enumTypeName = choice == null ? null : choice.Mapping.TypeDesc.FullName;

                for (int i = 0; i < elements.Length; i++)
                {
                    ElementAccessor element = elements[i];

                    if (element.Any)
                    {
                        anyCount++;
                        if (element.Name != null && element.Name.Length > 0)
                        {
                            namedAnys.Add(element);
                        }
                        else if (unnamedAny == null)
                        {
                            unnamedAny = element;
                        }
                    }
                    else if (choice != null)
                    {
                        if (o != null && o.GetType() == element.Mapping.TypeDesc.Type)
                        {
                            WriteElement(o, element, arrayName, writeAccessors);
                            return;
                        }
                    }
                    else
                    {
                        TypeDesc td = element.IsUnbounded ? element.Mapping.TypeDesc.CreateArrayTypeDesc() : element.Mapping.TypeDesc;
                        if (o.GetType() == td.Type)
                        {
                            WriteElement(o, element, arrayName, writeAccessors);
                            return;
                        }
                    }
                }

                if (anyCount > 0)
                {
                    var elem = o as XmlElement;
                    if (elem != null)
                    {
                        foreach (ElementAccessor element in namedAnys)
                        {
                            if (element.Name == elem.Name && element.Namespace == elem.NamespaceURI)
                            {
                                WriteElement(elem, element, arrayName, writeAccessors);
                                return;
                            }
                        }

                        if (choice != null)
                        {
                            throw CreateChoiceIdentifierValueException(choice.Mapping.TypeDesc.FullName, choice.MemberName, elem.Name, elem.NamespaceURI);
                        }

                        if (unnamedAny != null)
                        {
                            WriteElement(elem, unnamedAny, arrayName, writeAccessors);
                            return;
                        }

                        throw CreateUnknownAnyElementException(elem.Name, elem.NamespaceURI);
                    }
                }

                if (text != null)
                {
                    bool   useReflection = text.Mapping.TypeDesc.UseReflection;
                    string fullTypeName  = text.Mapping.TypeDesc.CSharpName;
                    WriteText(o, text);
                    return;
                }

                if (elements.Length > 0 && o != null)
                {
                    throw CreateUnknownTypeException(o);
                }
            }
        }
        private void WriteArrayItems(ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc, object o)
        {
            TypeDesc arrayElementTypeDesc = arrayTypeDesc.ArrayElementTypeDesc;

            var a = o as IEnumerable;

            //  #10593: This assert may not be true. We need more tests for this method.
            Debug.Assert(a != null);

            var e = a.GetEnumerator();

            if (e != null)
            {
                while (e.MoveNext())
                {
                    object ai = e.Current;
                    WriteElements(ai, null/*choiceName + "i"*/, elements, text, choice, (string)null/*arrayName + "a"*/, true, true);
                }
            }
        }
 private void WriteMember(SourceInfo source, string choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc memberTypeDesc, bool writeAccessors)
 {
     if (memberTypeDesc.IsArrayLike &&
         !(elements.Length == 1 && elements[0].Mapping is ArrayMapping))
         WriteArray(source, choiceSource, elements, text, choice, memberTypeDesc);
     else
         // NOTE: Use different variable name to work around reuse same variable name in different scope
         WriteElements(source, choiceSource, elements, text, choice, "a" + memberTypeDesc.Name, writeAccessors, memberTypeDesc.IsNullable);
 }
Exemplo n.º 25
0
 protected AccessorMapping(AccessorMapping mapping)
     : base(mapping)
 {
     this.typeDesc = mapping.typeDesc;
     this.attribute = mapping.attribute;
     this.elements = mapping.elements;
     this.sortedElements = mapping.sortedElements;
     this.text = mapping.text;
     this.choiceIdentifier = mapping.choiceIdentifier;
     this.xmlns = mapping.xmlns;
     this.ignore = mapping.ignore;
 }
        private void WriteArray(SourceInfo source, string choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc)
        {
            if (elements.Length == 0 && text == null) return;
            string arrayTypeName = arrayTypeDesc.CSharpName;
            string aName = "a" + arrayTypeDesc.Name;
            WriteArrayLocalDecl(arrayTypeName, aName, source, arrayTypeDesc);
            LocalBuilder aLoc = ilg.GetLocal(aName);
            if (arrayTypeDesc.IsNullable)
            {
                ilg.Ldloc(aLoc);
                ilg.Load(null);
                ilg.If(Cmp.NotEqualTo);
            }

            string cName = null;
            if (choice != null)
            {
                string choiceFullName = choice.Mapping.TypeDesc.CSharpName;
                SourceInfo choiceSourceInfo = new SourceInfo(choiceSource, null, choice.MemberInfo, null, ilg);
                cName = "c" + choice.Mapping.TypeDesc.Name;
                WriteArrayLocalDecl(choiceFullName + "[]", cName, choiceSourceInfo, choice.Mapping.TypeDesc);
                // write check for the choice identifier array
                Label labelEnd = ilg.DefineLabel();
                Label labelTrue = ilg.DefineLabel();
                LocalBuilder cLoc = ilg.GetLocal(cName);
                ilg.Ldloc(cLoc);
                ilg.Load(null);
                ilg.Beq(labelTrue);
                ilg.Ldloc(cLoc);
                ilg.Ldlen();
                ilg.Ldloc(aLoc);
                ilg.Ldlen();
                ilg.Clt();
                ilg.Br(labelEnd);
                ilg.MarkLabel(labelTrue);
                ilg.Ldc(true);
                ilg.MarkLabel(labelEnd);
                ilg.If();
                MethodInfo XmlSerializationWriter_CreateInvalidChoiceIdentifierValueException = typeof(XmlSerializationWriter).GetMethod(
                    "CreateInvalidChoiceIdentifierValueException",
                    CodeGenerator.InstanceBindingFlags,
                    new Type[] { typeof(String), typeof(String) }
                    );
                ilg.Ldarg(0);
                ilg.Ldstr(GetCSharpString(choice.Mapping.TypeDesc.FullName));
                ilg.Ldstr(GetCSharpString(choice.MemberName));
                ilg.Call(XmlSerializationWriter_CreateInvalidChoiceIdentifierValueException);
                ilg.Throw();
                ilg.EndIf();
            }

            WriteArrayItems(elements, text, choice, arrayTypeDesc, aName, cName);
            if (arrayTypeDesc.IsNullable)
            {
                ilg.EndIf();
            }
        }
        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(Res.GetString(Res.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(Res.GetString(Res.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(Res.GetString(Res.XmlInternalError));
                }
            }
            else {
                throw new InvalidOperationException(Res.GetString(Res.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(Res.GetString(Res.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(";");
            }
        }
        private void WriteArrayItems(ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc, string arrayName, string choiceName)
        {
            TypeDesc arrayElementTypeDesc = arrayTypeDesc.ArrayElementTypeDesc;

            if (arrayTypeDesc.IsEnumerable)
            {
                LocalBuilder eLoc = ilg.DeclareLocal(typeof(IEnumerator), "e");
                ilg.LoadAddress(ilg.GetVariable(arrayName));
                MethodInfo getEnumeratorMethod;

                if (arrayTypeDesc.IsPrivateImplementation)
                {
                    Type typeIEnumerable = typeof(IEnumerable);

                    getEnumeratorMethod = typeIEnumerable.GetMethod(
                        "GetEnumerator",
                        CodeGenerator.InstanceBindingFlags,
                        Array.Empty<Type>());

                    ilg.ConvertValue(arrayTypeDesc.Type, typeIEnumerable);
                }
                else if (arrayTypeDesc.IsGenericInterface)
                {
                    Type typeIEnumerable = typeof(IEnumerable<>).MakeGenericType(arrayElementTypeDesc.Type);

                    getEnumeratorMethod = typeIEnumerable.GetMethod(
                        "GetEnumerator",
                        CodeGenerator.InstanceBindingFlags,
                        Array.Empty<Type>());

                    ilg.ConvertValue(arrayTypeDesc.Type, typeIEnumerable);
                }
                else
                {
                    getEnumeratorMethod = arrayTypeDesc.Type.GetMethod(
                        "GetEnumerator",
                        Array.Empty<Type>());
                }
                ilg.Call(getEnumeratorMethod);
                ilg.ConvertValue(getEnumeratorMethod.ReturnType, typeof(IEnumerator));
                ilg.Stloc(eLoc);

                ilg.Ldloc(eLoc);
                ilg.Load(null);
                ilg.If(Cmp.NotEqualTo);
                ilg.WhileBegin();
                string arrayNamePlusA = (arrayName).Replace(arrayTypeDesc.Name, "") + "a" + arrayElementTypeDesc.Name;
                string arrayNamePlusI = (arrayName).Replace(arrayTypeDesc.Name, "") + "i" + arrayElementTypeDesc.Name;
                WriteLocalDecl(arrayNamePlusI, "e.Current", arrayElementTypeDesc.Type);
                WriteElements(new SourceInfo(arrayNamePlusI, null, null, arrayElementTypeDesc.Type, ilg), choiceName + "i", elements, text, choice, arrayNamePlusA, true, true);

                ilg.WhileBeginCondition(); // while (e.MoveNext())
                MethodInfo IEnumerator_MoveNext = typeof(IEnumerator).GetMethod(
                    "MoveNext",
                    CodeGenerator.InstanceBindingFlags,
                    Array.Empty<Type>());
                ilg.Ldloc(eLoc);
                ilg.Call(IEnumerator_MoveNext);
                ilg.WhileEndCondition();
                ilg.WhileEnd();

                ilg.EndIf(); // if (e != null)
            }
            else
            {
                // Filter out type specific for index (code match reusing local).
                string iPlusArrayName = "i" + (arrayName).Replace(arrayTypeDesc.Name, "");
                string arrayNamePlusA = (arrayName).Replace(arrayTypeDesc.Name, "") + "a" + arrayElementTypeDesc.Name;
                string arrayNamePlusI = (arrayName).Replace(arrayTypeDesc.Name, "") + "i" + arrayElementTypeDesc.Name;
                LocalBuilder localI = ilg.DeclareOrGetLocal(typeof(Int32), iPlusArrayName);
                ilg.For(localI, 0, ilg.GetLocal(arrayName));
                int count = elements.Length + (text == null ? 0 : 1);
                if (count > 1)
                {
                    WriteLocalDecl(arrayNamePlusI, RaCodeGen.GetStringForArrayMember(arrayName, iPlusArrayName, arrayTypeDesc), arrayElementTypeDesc.Type);
                    if (choice != null)
                    {
                        WriteLocalDecl(choiceName + "i", RaCodeGen.GetStringForArrayMember(choiceName, iPlusArrayName, choice.Mapping.TypeDesc), choice.Mapping.TypeDesc.Type);
                    }
                    WriteElements(new SourceInfo(arrayNamePlusI, null, null, arrayElementTypeDesc.Type, ilg), choiceName + "i", elements, text, choice, arrayNamePlusA, true, arrayElementTypeDesc.IsNullable);
                }
                else
                {
                    WriteElements(new SourceInfo(RaCodeGen.GetStringForArrayMember(arrayName, iPlusArrayName, arrayTypeDesc), null, null, arrayElementTypeDesc.Type, ilg), null, elements, text, choice, arrayNamePlusA, true, arrayElementTypeDesc.IsNullable);
                }
                ilg.EndFor();
            }
        }
Exemplo n.º 29
0
        void WriteArray(string source, string choiceSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, TypeDesc arrayTypeDesc) {
            if (elements.Length == 0 && text == null) return;
            Writer.WriteLine("{");
            Writer.Indent++;
            string arrayTypeName = arrayTypeDesc.CSharpName;
            WriteArrayLocalDecl(arrayTypeName, "a", source, arrayTypeDesc);
            if (arrayTypeDesc.IsNullable) {
                Writer.WriteLine("if (a != null) {");
                Writer.Indent++;
            }

            if (choice != null) {
                bool choiceUseReflection = choice.Mapping.TypeDesc.UseReflection;
                string choiceFullName = choice.Mapping.TypeDesc.CSharpName;
                WriteArrayLocalDecl(choiceFullName+"[]", "c", choiceSource, choice.Mapping.TypeDesc);
                // write check for the choice identifier array
                Writer.WriteLine("if (c == null || c.Length < a.Length) {");
                Writer.Indent++;
                Writer.Write("throw CreateInvalidChoiceIdentifierValueException(");
                WriteQuotedCSharpString(choice.Mapping.TypeDesc.FullName);
                Writer.Write(", ");
                WriteQuotedCSharpString(choice.MemberName);
                Writer.Write(");");
                Writer.Indent--;
                Writer.WriteLine("}");
            }

            WriteArrayItems(elements, text, choice, arrayTypeDesc, "a", "c");
            if (arrayTypeDesc.IsNullable) {
                Writer.Indent--;
                Writer.WriteLine("}");
            }
            Writer.Indent--;
            Writer.WriteLine("}");
        }
        private void WriteElements(SourceInfo source, string enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable)
        {
            if (elements.Length == 0 && text == null) return;
            if (elements.Length == 1 && text == null)
            {
                TypeDesc td = elements[0].IsUnbounded ? elements[0].Mapping.TypeDesc.CreateArrayTypeDesc() : elements[0].Mapping.TypeDesc;
                if (!elements[0].Any && !elements[0].Mapping.TypeDesc.IsOptionalValue)
                    source = source.CastTo(td);
                WriteElement(source, elements[0], arrayName, writeAccessors);
            }
            else
            {
                bool doEndIf = false;
                if (isNullable && choice == null)
                {
                    source.Load(typeof(object));
                    ilg.Load(null);
                    ilg.If(Cmp.NotEqualTo);
                    doEndIf = true;
                }
                int anyCount = 0;
                ArrayList namedAnys = new ArrayList();
                ElementAccessor unnamedAny = null; // can only have one
                bool wroteFirstIf = false;
                string enumTypeName = choice == null ? null : choice.Mapping.TypeDesc.FullName;

                for (int i = 0; i < elements.Length; i++)
                {
                    ElementAccessor element = elements[i];

                    if (element.Any)
                    {
                        anyCount++;
                        if (element.Name != null && element.Name.Length > 0)
                            namedAnys.Add(element);
                        else if (unnamedAny == null)
                            unnamedAny = element;
                    }
                    else if (choice != null)
                    {
                        string fullTypeName = element.Mapping.TypeDesc.CSharpName;
                        object enumValue;
                        string enumFullName = enumTypeName + ".@" + FindChoiceEnumValue(element, (EnumMapping)choice.Mapping, out enumValue);

                        if (wroteFirstIf) ilg.InitElseIf();
                        else { wroteFirstIf = true; ilg.InitIf(); }
                        ILGenLoad(enumSource, choice == null ? null : choice.Mapping.TypeDesc.Type);
                        ilg.Load(enumValue);
                        ilg.Ceq();
                        if (isNullable && !element.IsNullable)
                        {
                            Label labelFalse = ilg.DefineLabel();
                            Label labelEnd = ilg.DefineLabel();
                            ilg.Brfalse(labelFalse);
                            source.Load(typeof(object));
                            ilg.Load(null);
                            ilg.Cne();
                            ilg.Br_S(labelEnd);
                            ilg.MarkLabel(labelFalse);
                            ilg.Ldc(false);
                            ilg.MarkLabel(labelEnd);
                        }
                        ilg.AndIf();

                        WriteChoiceTypeCheck(source, fullTypeName, choice, enumFullName, element.Mapping.TypeDesc);

                        SourceInfo castedSource = source;
                        castedSource = source.CastTo(element.Mapping.TypeDesc);
                        WriteElement(element.Any ? source : castedSource, element, arrayName, writeAccessors);
                    }
                    else
                    {
                        TypeDesc td = element.IsUnbounded ? element.Mapping.TypeDesc.CreateArrayTypeDesc() : element.Mapping.TypeDesc;
                        string fullTypeName = td.CSharpName;
                        if (wroteFirstIf) ilg.InitElseIf();
                        else { wroteFirstIf = true; ilg.InitIf(); }
                        WriteInstanceOf(source, td.Type);
                        // WriteInstanceOf leave bool on the stack
                        ilg.AndIf();
                        SourceInfo castedSource = source;
                        castedSource = source.CastTo(td);
                        WriteElement(element.Any ? source : castedSource, element, arrayName, writeAccessors);
                    }
                }
                if (wroteFirstIf)
                {
                    if (anyCount > 0)
                    {
                        // See "else " below
                        if (elements.Length - anyCount > 0)
                        { // NOOP
                        }
                        else ilg.EndIf();
                    }
                }
                if (anyCount > 0)
                {
                    if (elements.Length - anyCount > 0) ilg.InitElseIf();
                    else ilg.InitIf();

                    string fullTypeName = typeof(XmlElement).FullName;

                    source.Load(typeof(object));
                    ilg.IsInst(typeof(XmlElement));
                    ilg.Load(null);
                    ilg.Cne();
                    ilg.AndIf();

                    LocalBuilder elemLoc = ilg.DeclareLocal(typeof(XmlElement), "elem");
                    source.Load(typeof(XmlElement));
                    ilg.Stloc(elemLoc);

                    int c = 0;

                    foreach (ElementAccessor element in namedAnys)
                    {
                        if (c++ > 0) ilg.InitElseIf();
                        else ilg.InitIf();

                        string enumFullName = null;

                        Label labelEnd, labelFalse;
                        if (choice != null)
                        {
                            object enumValue;
                            enumFullName = enumTypeName + ".@" + FindChoiceEnumValue(element, (EnumMapping)choice.Mapping, out enumValue);
                            labelFalse = ilg.DefineLabel();
                            labelEnd = ilg.DefineLabel();
                            ILGenLoad(enumSource, choice == null ? null : choice.Mapping.TypeDesc.Type);
                            ilg.Load(enumValue);
                            ilg.Bne(labelFalse);
                            if (isNullable && !element.IsNullable)
                            {
                                source.Load(typeof(object));
                                ilg.Load(null);
                                ilg.Cne();
                            }
                            else
                            {
                                ilg.Ldc(true);
                            }
                            ilg.Br(labelEnd);
                            ilg.MarkLabel(labelFalse);
                            ilg.Ldc(false);
                            ilg.MarkLabel(labelEnd);
                            ilg.AndIf();
                        }
                        labelFalse = ilg.DefineLabel();
                        labelEnd = ilg.DefineLabel();
                        MethodInfo XmlNode_get_Name = typeof(XmlNode).GetMethod(
                            "get_Name",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        MethodInfo XmlNode_get_NamespaceURI = typeof(XmlNode).GetMethod(
                            "get_NamespaceURI",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        ilg.Ldloc(elemLoc);
                        ilg.Call(XmlNode_get_Name);
                        ilg.Ldstr(GetCSharpString(element.Name));
                        MethodInfo String_op_Equality = typeof(string).GetMethod(
                            "op_Equality",
                            CodeGenerator.StaticBindingFlags,
                            new Type[] { typeof(string), typeof(string) }
                            );
                        ilg.Call(String_op_Equality);
                        ilg.Brfalse(labelFalse);
                        ilg.Ldloc(elemLoc);
                        ilg.Call(XmlNode_get_NamespaceURI);
                        ilg.Ldstr(GetCSharpString(element.Namespace));
                        ilg.Call(String_op_Equality);
                        ilg.Br(labelEnd);
                        ilg.MarkLabel(labelFalse);
                        ilg.Ldc(false);
                        ilg.MarkLabel(labelEnd);
                        if (choice != null) ilg.If();
                        else ilg.AndIf();
                        WriteElement(new SourceInfo("elem", null, null, elemLoc.LocalType, ilg), element, arrayName, writeAccessors);

                        if (choice != null)
                        {
                            ilg.Else();

                            MethodInfo XmlSerializationWriter_CreateChoiceIdentifierValueException = typeof(XmlSerializationWriter).GetMethod(
                                "CreateChoiceIdentifierValueException",
                                CodeGenerator.InstanceBindingFlags,
                                new Type[] { typeof(String), typeof(String), typeof(String), typeof(String) }
                                );
                            ilg.Ldarg(0);
                            ilg.Ldstr(GetCSharpString(enumFullName));
                            ilg.Ldstr(GetCSharpString(choice.MemberName));
                            ilg.Ldloc(elemLoc);
                            ilg.Call(XmlNode_get_Name);
                            ilg.Ldloc(elemLoc);
                            ilg.Call(XmlNode_get_NamespaceURI);
                            ilg.Call(XmlSerializationWriter_CreateChoiceIdentifierValueException);
                            ilg.Throw();
                            ilg.EndIf();
                        }
                    }
                    if (c > 0)
                    {
                        ilg.Else();
                    }
                    if (unnamedAny != null)
                    {
                        WriteElement(new SourceInfo("elem", null, null, elemLoc.LocalType, ilg), unnamedAny, arrayName, writeAccessors);
                    }
                    else
                    {
                        MethodInfo XmlSerializationWriter_CreateUnknownAnyElementException = typeof(XmlSerializationWriter).GetMethod(
                            "CreateUnknownAnyElementException",
                            CodeGenerator.InstanceBindingFlags,
                            new Type[] { typeof(String), typeof(String) }
                            );
                        ilg.Ldarg(0);
                        ilg.Ldloc(elemLoc);
                        MethodInfo XmlNode_get_Name = typeof(XmlNode).GetMethod(
                            "get_Name",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        MethodInfo XmlNode_get_NamespaceURI = typeof(XmlNode).GetMethod(
                            "get_NamespaceURI",
                            CodeGenerator.InstanceBindingFlags,
                            Array.Empty<Type>()
                            );
                        ilg.Call(XmlNode_get_Name);
                        ilg.Ldloc(elemLoc);
                        ilg.Call(XmlNode_get_NamespaceURI);
                        ilg.Call(XmlSerializationWriter_CreateUnknownAnyElementException);
                        ilg.Throw();
                    }
                    if (c > 0)
                    {
                        ilg.EndIf();
                    }
                }
                if (text != null)
                {
                    string fullTypeName = text.Mapping.TypeDesc.CSharpName;
                    if (elements.Length > 0)
                    {
                        ilg.InitElseIf();
                        WriteInstanceOf(source, text.Mapping.TypeDesc.Type);
                        ilg.AndIf();
                        SourceInfo castedSource = source.CastTo(text.Mapping.TypeDesc);
                        WriteText(castedSource, text);
                    }
                    else
                    {
                        SourceInfo castedSource = source.CastTo(text.Mapping.TypeDesc);
                        WriteText(castedSource, text);
                    }
                }
                if (elements.Length > 0)
                {
                    if (isNullable)
                    {
                        ilg.InitElseIf();
                        source.Load(null);
                        ilg.Load(null);
                        ilg.AndIf(Cmp.NotEqualTo);
                    }
                    else
                    {
                        ilg.Else();
                    }

                    MethodInfo XmlSerializationWriter_CreateUnknownTypeException = typeof(XmlSerializationWriter).GetMethod(
                        "CreateUnknownTypeException",
                        CodeGenerator.InstanceBindingFlags,
                        new Type[] { typeof(Object) });
                    ilg.Ldarg(0);
                    source.Load(typeof(object));
                    ilg.Call(XmlSerializationWriter_CreateUnknownTypeException);
                    ilg.Throw();

                    ilg.EndIf();
                }
                // See ilg.If() cond above
                if (doEndIf) // if (isNullable && choice == null)
                    ilg.EndIf();
            }
        }
Exemplo n.º 31
0
 void WriteElements(string source, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable) {
     WriteElements(source, null, elements, text, choice, arrayName, writeAccessors, isNullable);
 }
 private void WriteChoiceTypeCheck(SourceInfo source, string fullTypeName, ChoiceIdentifierAccessor choice, string enumName, TypeDesc typeDesc)
 {
     Label labelFalse = ilg.DefineLabel();
     Label labelEnd = ilg.DefineLabel();
     source.Load(typeof(object));
     ilg.Load(null);
     ilg.Beq(labelFalse);
     WriteInstanceOf(source, typeDesc.Type);
     // Negative
     ilg.Ldc(false);
     ilg.Ceq();
     ilg.Br(labelEnd);
     ilg.MarkLabel(labelFalse);
     ilg.Ldc(false);
     ilg.MarkLabel(labelEnd);
     ilg.If();
     MethodInfo XmlSerializationWriter_CreateMismatchChoiceException = typeof(XmlSerializationWriter).GetMethod(
         "CreateMismatchChoiceException",
         CodeGenerator.InstanceBindingFlags,
         new Type[] { typeof(String), typeof(String), typeof(String) }
         );
     ilg.Ldarg(0);
     ilg.Ldstr(GetCSharpString(typeDesc.FullName));
     ilg.Ldstr(GetCSharpString(choice.MemberName));
     ilg.Ldstr(GetCSharpString(enumName));
     ilg.Call(XmlSerializationWriter_CreateMismatchChoiceException);
     ilg.Throw();
     ilg.EndIf();
 }
Exemplo n.º 33
0
        void WriteChoiceTypeCheck(string source, string fullTypeName, bool useReflection, ChoiceIdentifierAccessor choice, string enumName, TypeDesc typeDesc) {

            Writer.Write("if (((object)");
            Writer.Write(source);
            Writer.Write(") != null && !(");
            WriteInstanceOf(source, fullTypeName, useReflection);
            Writer.Write(")) throw CreateMismatchChoiceException(");
            WriteQuotedCSharpString(typeDesc.FullName);
            Writer.Write(", ");
            WriteQuotedCSharpString(choice.MemberName);
            Writer.Write(", ");
            WriteQuotedCSharpString(enumName);
            Writer.WriteLine(");");
        }
 private void WriteElements(string source, string enumSource, ElementAccessor[] elements, TextAccessor text, ChoiceIdentifierAccessor choice, string arrayName, bool writeAccessors, bool isNullable)
 {
     if ((elements.Length != 0) || (text != null))
     {
         if ((elements.Length == 1) && (text == null))
         {
             TypeDesc desc = elements[0].IsUnbounded ? elements[0].Mapping.TypeDesc.CreateArrayTypeDesc() : elements[0].Mapping.TypeDesc;
             if ((!elements[0].Any && !elements[0].Mapping.TypeDesc.UseReflection) && !elements[0].Mapping.TypeDesc.IsOptionalValue)
             {
                 source = "((" + desc.CSharpName + ")" + source + ")";
             }
             this.WriteElement(source, elements[0], arrayName, writeAccessors);
         }
         else
         {
             if (isNullable && (choice == null))
             {
                 base.Writer.Write("if ((object)(");
                 base.Writer.Write(source);
                 base.Writer.Write(") != null)");
             }
             base.Writer.WriteLine("{");
             IndentedWriter writer = base.Writer;
             writer.Indent++;
             int num = 0;
             ArrayList list = new ArrayList();
             ElementAccessor element = null;
             bool flag = false;
             string str = (choice == null) ? null : choice.Mapping.TypeDesc.FullName;
             for (int i = 0; i < elements.Length; i++)
             {
                 ElementAccessor accessor2 = elements[i];
                 if (accessor2.Any)
                 {
                     num++;
                     if ((accessor2.Name != null) && (accessor2.Name.Length > 0))
                     {
                         list.Add(accessor2);
                     }
                     else if (element == null)
                     {
                         element = accessor2;
                     }
                 }
                 else if (choice != null)
                 {
                     bool useReflection = accessor2.Mapping.TypeDesc.UseReflection;
                     string cSharpName = accessor2.Mapping.TypeDesc.CSharpName;
                     bool flag3 = choice.Mapping.TypeDesc.UseReflection;
                     string s = (flag3 ? "" : (str + ".@")) + this.FindChoiceEnumValue(accessor2, (EnumMapping) choice.Mapping, flag3);
                     if (flag)
                     {
                         base.Writer.Write("else ");
                     }
                     else
                     {
                         flag = true;
                     }
                     base.Writer.Write("if (");
                     base.Writer.Write(flag3 ? base.RaCodeGen.GetStringForEnumLongValue(enumSource, flag3) : enumSource);
                     base.Writer.Write(" == ");
                     base.Writer.Write(s);
                     if (isNullable && !accessor2.IsNullable)
                     {
                         base.Writer.Write(" && ((object)(");
                         base.Writer.Write(source);
                         base.Writer.Write(") != null)");
                     }
                     base.Writer.WriteLine(") {");
                     IndentedWriter writer2 = base.Writer;
                     writer2.Indent++;
                     this.WriteChoiceTypeCheck(source, cSharpName, useReflection, choice, s, accessor2.Mapping.TypeDesc);
                     string str4 = source;
                     if (!useReflection)
                     {
                         str4 = "((" + cSharpName + ")" + source + ")";
                     }
                     this.WriteElement(accessor2.Any ? source : str4, accessor2, arrayName, writeAccessors);
                     IndentedWriter writer3 = base.Writer;
                     writer3.Indent--;
                     base.Writer.WriteLine("}");
                 }
                 else
                 {
                     bool flag4 = accessor2.Mapping.TypeDesc.UseReflection;
                     TypeDesc desc2 = accessor2.IsUnbounded ? accessor2.Mapping.TypeDesc.CreateArrayTypeDesc() : accessor2.Mapping.TypeDesc;
                     string escapedTypeName = desc2.CSharpName;
                     if (flag)
                     {
                         base.Writer.Write("else ");
                     }
                     else
                     {
                         flag = true;
                     }
                     base.Writer.Write("if (");
                     this.WriteInstanceOf(source, escapedTypeName, flag4);
                     base.Writer.WriteLine(") {");
                     IndentedWriter writer4 = base.Writer;
                     writer4.Indent++;
                     string str6 = source;
                     if (!flag4)
                     {
                         str6 = "((" + escapedTypeName + ")" + source + ")";
                     }
                     this.WriteElement(accessor2.Any ? source : str6, accessor2, arrayName, writeAccessors);
                     IndentedWriter writer5 = base.Writer;
                     writer5.Indent--;
                     base.Writer.WriteLine("}");
                 }
             }
             if (num > 0)
             {
                 if ((elements.Length - num) > 0)
                 {
                     base.Writer.Write("else ");
                 }
                 string fullName = typeof(XmlElement).FullName;
                 base.Writer.Write("if (");
                 base.Writer.Write(source);
                 base.Writer.Write(" is ");
                 base.Writer.Write(fullName);
                 base.Writer.WriteLine(") {");
                 IndentedWriter writer6 = base.Writer;
                 writer6.Indent++;
                 base.Writer.Write(fullName);
                 base.Writer.Write(" elem = (");
                 base.Writer.Write(fullName);
                 base.Writer.Write(")");
                 base.Writer.Write(source);
                 base.Writer.WriteLine(";");
                 int num3 = 0;
                 foreach (ElementAccessor accessor3 in list)
                 {
                     if (num3++ > 0)
                     {
                         base.Writer.Write("else ");
                     }
                     string str8 = null;
                     bool flag1 = accessor3.Mapping.TypeDesc.UseReflection;
                     if (choice != null)
                     {
                         bool flag5 = choice.Mapping.TypeDesc.UseReflection;
                         str8 = (flag5 ? "" : (str + ".@")) + this.FindChoiceEnumValue(accessor3, (EnumMapping) choice.Mapping, flag5);
                         base.Writer.Write("if (");
                         base.Writer.Write(flag5 ? base.RaCodeGen.GetStringForEnumLongValue(enumSource, flag5) : enumSource);
                         base.Writer.Write(" == ");
                         base.Writer.Write(str8);
                         if (isNullable && !accessor3.IsNullable)
                         {
                             base.Writer.Write(" && ((object)(");
                             base.Writer.Write(source);
                             base.Writer.Write(") != null)");
                         }
                         base.Writer.WriteLine(") {");
                         IndentedWriter writer7 = base.Writer;
                         writer7.Indent++;
                     }
                     base.Writer.Write("if (elem.Name == ");
                     base.WriteQuotedCSharpString(accessor3.Name);
                     base.Writer.Write(" && elem.NamespaceURI == ");
                     base.WriteQuotedCSharpString(accessor3.Namespace);
                     base.Writer.WriteLine(") {");
                     IndentedWriter writer8 = base.Writer;
                     writer8.Indent++;
                     this.WriteElement("elem", accessor3, arrayName, writeAccessors);
                     if (choice != null)
                     {
                         IndentedWriter writer9 = base.Writer;
                         writer9.Indent--;
                         base.Writer.WriteLine("}");
                         base.Writer.WriteLine("else {");
                         IndentedWriter writer10 = base.Writer;
                         writer10.Indent++;
                         base.Writer.WriteLine("// throw Value '{0}' of the choice identifier '{1}' does not match element '{2}' from namespace '{3}'.");
                         base.Writer.Write("throw CreateChoiceIdentifierValueException(");
                         base.WriteQuotedCSharpString(str8);
                         base.Writer.Write(", ");
                         base.WriteQuotedCSharpString(choice.MemberName);
                         base.Writer.WriteLine(", elem.Name, elem.NamespaceURI);");
                         IndentedWriter writer11 = base.Writer;
                         writer11.Indent--;
                         base.Writer.WriteLine("}");
                     }
                     IndentedWriter writer12 = base.Writer;
                     writer12.Indent--;
                     base.Writer.WriteLine("}");
                 }
                 if (num3 > 0)
                 {
                     base.Writer.WriteLine("else {");
                     IndentedWriter writer13 = base.Writer;
                     writer13.Indent++;
                 }
                 if (element != null)
                 {
                     this.WriteElement("elem", element, arrayName, writeAccessors);
                 }
                 else
                 {
                     base.Writer.WriteLine("throw CreateUnknownAnyElementException(elem.Name, elem.NamespaceURI);");
                 }
                 if (num3 > 0)
                 {
                     IndentedWriter writer14 = base.Writer;
                     writer14.Indent--;
                     base.Writer.WriteLine("}");
                 }
                 IndentedWriter writer15 = base.Writer;
                 writer15.Indent--;
                 base.Writer.WriteLine("}");
             }
             if (text != null)
             {
                 bool flag6 = text.Mapping.TypeDesc.UseReflection;
                 string str9 = text.Mapping.TypeDesc.CSharpName;
                 if (elements.Length > 0)
                 {
                     base.Writer.Write("else ");
                     base.Writer.Write("if (");
                     this.WriteInstanceOf(source, str9, flag6);
                     base.Writer.WriteLine(") {");
                     IndentedWriter writer16 = base.Writer;
                     writer16.Indent++;
                     string str10 = source;
                     if (!flag6)
                     {
                         str10 = "((" + str9 + ")" + source + ")";
                     }
                     this.WriteText(str10, text);
                     IndentedWriter writer17 = base.Writer;
                     writer17.Indent--;
                     base.Writer.WriteLine("}");
                 }
                 else
                 {
                     string str11 = source;
                     if (!flag6)
                     {
                         str11 = "((" + str9 + ")" + source + ")";
                     }
                     this.WriteText(str11, text);
                 }
             }
             if (elements.Length > 0)
             {
                 base.Writer.Write("else ");
                 if (isNullable)
                 {
                     base.Writer.Write(" if ((object)(");
                     base.Writer.Write(source);
                     base.Writer.Write(") != null)");
                 }
                 base.Writer.WriteLine("{");
                 IndentedWriter writer18 = base.Writer;
                 writer18.Indent++;
                 base.Writer.Write("throw CreateUnknownTypeException(");
                 base.Writer.Write(source);
                 base.Writer.WriteLine(");");
                 IndentedWriter writer19 = base.Writer;
                 writer19.Indent--;
                 base.Writer.WriteLine("}");
             }
             IndentedWriter writer20 = base.Writer;
             writer20.Indent--;
             base.Writer.WriteLine("}");
         }
     }
 }