private bool WriteDerivedTypes(StructMapping mapping, string n, string ns, object o, bool isNullable)
        {
            Type t = o.GetType();

            for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping)
            {
                if (t == derived.TypeDesc.Type)
                {
                    WriteStructMethod(derived, n, ns, o, isNullable, needType: true);
                    return(true);
                }

                if (WriteDerivedTypes(derived, n, ns, o, isNullable))
                {
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 2
0
        internal void SetSequence()
        {
            if (TypeDesc.IsRoot)
            {
                return;
            }

            StructMapping start = this;

            // find first mapping that does not have the sequence set
            while (start.BaseMapping != null && !start.BaseMapping.IsSequence && !start.BaseMapping.TypeDesc.IsRoot)
            {
                start = start.BaseMapping;
            }

            start.IsSequence = true;
            for (StructMapping derived = start.DerivedMappings; derived != null; derived = derived.NextDerivedMapping)
            {
                derived.SetSequence();
            }
        }
Exemplo n.º 3
0
        private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter)
        {
            if (mapping.IsFullyInitialized)
            {
                return(true);
            }
            if (model.TypeDesc.BaseTypeDesc != null)
            {
                StructMapping baseMapping = ImportStructLikeMapping((StructModel)_modelScope.GetTypeModel(model.Type.BaseType, false), limiter);

                // check to see if the import of the baseMapping was deferred
                int baseIndex = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping);
                if (baseIndex < 0)
                {
                    mapping.BaseMapping = baseMapping;
                }
                else
                {
                    // the import of the baseMapping was deferred, make sure that the derived mappings is deferred as well
                    if (!limiter.DeferredWorkItems.Contains(mapping))
                    {
                        limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    }
                    // make sure that baseMapping get processed before the derived
                    int top = limiter.DeferredWorkItems.Count - 1;
                    if (baseIndex < top)
                    {
                        ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex];
                        limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top];
                        limiter.DeferredWorkItems[top]       = baseMappingWorkItem;
                    }
                    return(false);
                }
            }
            ArrayList members = new ArrayList();

            foreach (MemberInfo memberInfo in model.GetMemberInfos())
            {
                if (!(memberInfo is FieldInfo) && !(memberInfo is PropertyInfo))
                {
                    continue;
                }
                SoapAttributes memberAttrs = GetAttributes(memberInfo);
                if (memberAttrs.SoapIgnore)
                {
                    continue;
                }
                FieldModel fieldModel = model.GetFieldModel(memberInfo);
                if (fieldModel == null)
                {
                    continue;
                }
                MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace, limiter);
                if (member == null)
                {
                    continue;
                }

                if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum && !member.TypeDesc.IsOptionalValue)
                {
                    if (model.TypeDesc.IsValueType)
                    {
                        throw new NotSupportedException(SR.Format(SR.XmlRpcRefsInValueType, model.TypeDesc.FullName));
                    }
                    if (member.TypeDesc.IsValueType)
                    {
                        throw new NotSupportedException(SR.Format(SR.XmlRpcNestedValueType, member.TypeDesc.FullName));
                    }
                }
                if (mapping.BaseMapping != null)
                {
                    if (mapping.BaseMapping.Declares(member, mapping.TypeName))
                    {
                        continue;
                    }
                }
                members.Add(member);
            }
            mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping));
            if (mapping.BaseMapping == null)
            {
                mapping.BaseMapping = GetRootMapping();
            }
            IncludeTypes(model.Type, limiter);

            return(true);
        }
Exemplo n.º 4
0
        private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter)
        {
            if (model.TypeDesc.Kind == TypeKind.Root)
            {
                return(GetRootMapping());
            }

            SoapAttributes a = GetAttributes(model.Type);

            string typeNs = _defaultNs;

            if (a.SoapType != null && a.SoapType.Namespace != null)
            {
                typeNs = a.SoapType.Namespace;
            }
            string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name);

            typeName = XmlConvert.EncodeLocalName(typeName);

            StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc);

            if (mapping == null)
            {
                mapping           = new StructMapping();
                mapping.IsSoap    = true;
                mapping.TypeDesc  = model.TypeDesc;
                mapping.Namespace = typeNs;
                mapping.TypeName  = typeName;
                if (a.SoapType != null)
                {
                    mapping.IncludeInSchema = a.SoapType.IncludeInSchema;
                }
                _typeScope.AddTypeMapping(mapping);
                _types.Add(typeName, typeNs, mapping);
                if (limiter.IsExceededLimit)
                {
                    limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping));
                    return(mapping);
                }

                limiter.Depth++;

                InitializeStructMembers(mapping, model, limiter);
                while (limiter.DeferredWorkItems.Count > 0)
                {
                    int index = limiter.DeferredWorkItems.Count - 1;
                    ImportStructWorkItem item = limiter.DeferredWorkItems[index];
                    if (InitializeStructMembers(item.Mapping, item.Model, limiter))
                    {
                        //
                        // if InitializeStructMembers returns true, then there were *no* changes to the DeferredWorkItems
                        //
#if DEBUG
                        // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
                        if (index != limiter.DeferredWorkItems.Count - 1)
                        {
                            throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed"));
                        }
                        if (item != limiter.DeferredWorkItems[index])
                        {
                            throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed"));
                        }
#endif
                        // Remove the last work item
                        limiter.DeferredWorkItems.RemoveAt(index);
                    }
                }
                limiter.Depth--;
            }
            return(mapping);
        }
        private void WriteStructMethod(StructMapping mapping, string n, string ns, object o, bool isNullable, bool needType, XmlMapping parentMapping = null)
        {
            if (mapping.IsSoap && mapping.TypeDesc.IsRoot)
            {
                return;
            }

            if (!mapping.IsSoap)
            {
                if (o == null)
                {
                    if (isNullable)
                    {
                        WriteNullTagLiteral(n, ns);
                    }
                    return;
                }

                if (!needType &&
                    o.GetType() != mapping.TypeDesc.Type)
                {
                    if (WriteDerivedTypes(mapping, n, ns, o, isNullable))
                    {
                        return;
                    }

                    if (mapping.TypeDesc.IsRoot)
                    {
                        if (WriteEnumAndArrayTypes(mapping, o, n, ns, parentMapping))
                        {
                            return;
                        }

                        WriteTypedPrimitive(n, ns, o, true);
                        return;
                    }

                    throw CreateUnknownTypeException(o);
                }
            }

            if (!mapping.TypeDesc.IsAbstract)
            {
                if (mapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(mapping.TypeDesc.Type))
                {
                    EscapeName = false;
                }

                XmlSerializerNamespaces xmlnsSource = null;
                MemberMapping[]         members     = TypeScope.GetAllMembers(mapping);
                int xmlnsMember = FindXmlnsIndex(members);
                if (xmlnsMember >= 0)
                {
                    MemberMapping member = members[xmlnsMember];
                    xmlnsSource = (XmlSerializerNamespaces)GetMemberValue(o, member.Name);
                }

                if (!mapping.IsSoap)
                {
                    WriteStartElement(n, ns, o, false, xmlnsSource);

                    if (!mapping.TypeDesc.IsRoot)
                    {
                        if (needType)
                        {
                            WriteXsiType(mapping.TypeName, mapping.Namespace);
                        }
                    }
                }
                else if (xmlnsSource != null)
                {
                    WriteNamespaceDeclarations(xmlnsSource);
                }

                for (int i = 0; i < members.Length; i++)
                {
                    MemberMapping m           = members[i];
                    string        memberName  = m.Name;
                    object        memberValue = GetMemberValue(o, memberName);

                    bool isSpecified   = true;
                    bool shouldPersist = true;
                    if (m.CheckSpecified != SpecifiedAccessor.None)
                    {
                        string specifiedMemberName = m.Name + "Specified";
                        isSpecified = (bool)GetMemberValue(o, specifiedMemberName);
                    }

                    if (m.CheckShouldPersist)
                    {
                        string     methodInvoke = "ShouldSerialize" + m.Name;
                        MethodInfo method       = o.GetType().GetTypeInfo().GetDeclaredMethod(methodInvoke);
                        shouldPersist = (bool)method.Invoke(o, Array.Empty <object>());
                    }

                    if (m.Attribute != null)
                    {
                        if (isSpecified && shouldPersist)
                        {
                            WriteMember(memberValue, m.Attribute, m.TypeDesc, o);
                        }
                    }
                }

                for (int i = 0; i < members.Length; i++)
                {
                    MemberMapping m           = members[i];
                    string        memberName  = m.Name;
                    object        memberValue = GetMemberValue(o, memberName);

                    bool isSpecified   = true;
                    bool shouldPersist = true;
                    if (m.CheckSpecified != SpecifiedAccessor.None)
                    {
                        string specifiedMemberName = m.Name + "Specified";
                        isSpecified = (bool)GetMemberValue(o, specifiedMemberName);
                    }

                    if (m.CheckShouldPersist)
                    {
                        string     methodInvoke = "ShouldSerialize" + m.Name;
                        MethodInfo method       = o.GetType().GetTypeInfo().GetDeclaredMethod(methodInvoke);
                        shouldPersist = (bool)method.Invoke(o, Array.Empty <object>());
                    }

                    if (m.Xmlns != null)
                    {
                        continue;
                    }

                    bool checkShouldPersist = m.CheckShouldPersist && (m.Elements.Length > 0 || m.Text != null);

                    if (!checkShouldPersist)
                    {
                        shouldPersist = true;
                    }

                    object choiceSource = null;
                    if (m.ChoiceIdentifier != null)
                    {
                        choiceSource = GetMemberValue(o, m.ChoiceIdentifier.MemberName);
                    }

                    if (isSpecified && shouldPersist)
                    {
                        WriteMember(memberValue, choiceSource, m.ElementsSortedByDerivation, m.Text, m.ChoiceIdentifier, m.TypeDesc, true, parentMapping);
                    }
                }
                if (!mapping.IsSoap)
                {
                    WriteEndElement(o);
                }
            }
        }