XmlObjectSerializerWriteContext.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / XmlObjectSerializerWriteContext.cs / 1305376 / XmlObjectSerializerWriteContext.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime.Serialization 
{
    using System; 
    using System.Collections; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Xml; 
    using System.Collections.Generic;
    using System.Xml.Serialization; 
    using System.ServiceModel.Diagnostics; 
    using System.Security;
    using System.Security.Permissions; 
    using System.Runtime.CompilerServices;
    using System.Runtime.Serialization.Diagnostics;

#if USE_REFEMIT 
    public class XmlObjectSerializerWriteContext : XmlObjectSerializerContext
#else 
    internal class XmlObjectSerializerWriteContext : XmlObjectSerializerContext 
#endif
    { 
        ObjectReferenceStack byValObjectsInScope = new ObjectReferenceStack();
        XmlSerializableWriter xmlSerializableWriter;
        const int depthToCheckCyclicReference = 512;
        protected bool preserveObjectReferences; 
        ObjectToIdCache serializedObjects;
        bool isGetOnlyCollection; 
 
        internal static XmlObjectSerializerWriteContext CreateContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver)
        { 
            return (serializer.PreserveObjectReferences || serializer.DataContractSurrogate != null)
                ? new XmlObjectSerializerWriteContextComplex(serializer, rootTypeDataContract, dataContractResolver)
                : new XmlObjectSerializerWriteContext(serializer, rootTypeDataContract, dataContractResolver);
        } 

        internal static XmlObjectSerializerWriteContext CreateContext(NetDataContractSerializer serializer, Hashtable surrogateDataContracts) 
        { 
            return new XmlObjectSerializerWriteContextComplex(serializer, surrogateDataContracts);
        } 

        protected XmlObjectSerializerWriteContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver resolver)
            : base(serializer, rootTypeDataContract, resolver)
        { 
        }
 
        protected XmlObjectSerializerWriteContext(NetDataContractSerializer serializer) 
            : base(serializer)
        { 
        }

        internal XmlObjectSerializerWriteContext(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject)
            : base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject) 
        {
        } 
 
#if USE_REFEMIT
        internal ObjectToIdCache SerializedObjects 
#else
        protected ObjectToIdCache SerializedObjects
#endif
        { 
            get
            { 
                if (serializedObjects == null) 
                    serializedObjects = new ObjectToIdCache();
                return serializedObjects; 
            }
        }

        internal override bool IsGetOnlyCollection 
        {
            get { return this.isGetOnlyCollection; } 
            set { this.isGetOnlyCollection = value; } 
        }
 
#if USE_REFEMIT
        public void StoreIsGetOnlyCollection()
#else
        internal void StoreIsGetOnlyCollection() 
#endif
        { 
            this.isGetOnlyCollection = true; 
        }
 
        public void InternalSerializeReference(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
        {
            if (!OnHandleReference(xmlWriter, obj, true /*canContainCyclicReference*/))
                InternalSerialize(xmlWriter, obj, isDeclaredType, writeXsiType, declaredTypeID, declaredTypeHandle); 
            OnEndHandleReference(xmlWriter, obj, true /*canContainCyclicReference*/);
        } 
 
        public virtual void InternalSerialize(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
        { 
            if (writeXsiType)
            {
                Type declaredType = Globals.TypeOfObject;
                SerializeWithXsiType(xmlWriter, obj, Type.GetTypeHandle(obj), null/*type*/, -1, declaredType.TypeHandle, declaredType); 
            }
            else if (isDeclaredType) 
            { 
                DataContract contract = GetDataContract(declaredTypeID, declaredTypeHandle);
                SerializeWithoutXsiType(contract, xmlWriter, obj, declaredTypeHandle); 
            }
            else
            {
                RuntimeTypeHandle objTypeHandle = Type.GetTypeHandle(obj); 
                if (declaredTypeHandle.Equals(objTypeHandle))
                { 
                    DataContract dataContract = (declaredTypeID >= 0) 
                        ? GetDataContract(declaredTypeID, declaredTypeHandle)
                        : GetDataContract(declaredTypeHandle, null /*type*/); 
                    SerializeWithoutXsiType(dataContract, xmlWriter, obj, declaredTypeHandle);
                }
                else
                { 
                    SerializeWithXsiType(xmlWriter, obj, objTypeHandle, null /*type*/, declaredTypeID, declaredTypeHandle, Type.GetTypeFromHandle(declaredTypeHandle));
                } 
            } 
        }
 
        internal void SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
        {
            if (OnHandleIsReference(xmlWriter, dataContract, obj))
                return; 
            if (dataContract.KnownDataContracts != null)
            { 
                scopedKnownTypes.Push(dataContract.KnownDataContracts); 
                WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle);
                scopedKnownTypes.Pop(); 
            }
            else
            {
                WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle); 
            }
        } 
 
        internal virtual void SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType)
        { 
            bool verifyKnownType = false;
            Type declaredType = rootTypeDataContract.OriginalUnderlyingType;

            if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType)) 
            {
                if (DataContractResolver != null) 
                { 
                    WriteResolvedTypeInfo(xmlWriter, graphType, declaredType);
                } 
            }
            else if (!declaredType.IsArray) //Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item
            {
                verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, rootTypeDataContract); 
            }
            SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, originalDeclaredTypeHandle, declaredType); 
        } 

        protected virtual void SerializeWithXsiType(XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) 
        {
            DataContract dataContract;
            bool verifyKnownType = false;
            if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType)) 
            {
                dataContract = GetDataContractSkipValidation(DataContract.GetId(objectTypeHandle), objectTypeHandle, objectType); 
                if (OnHandleIsReference(xmlWriter, dataContract, obj)) 
                    return;
                if (this.Mode == SerializationMode.SharedType && dataContract.IsValidContract(this.Mode)) 
                    dataContract = dataContract.GetValidContract(this.Mode);
                else
                    dataContract = GetDataContract(declaredTypeHandle, declaredType);
                if (!WriteClrTypeInfo(xmlWriter, dataContract) && DataContractResolver != null) 
                {
                    if (objectType == null) 
                    { 
                        objectType = Type.GetTypeFromHandle(objectTypeHandle);
                    } 
                    WriteResolvedTypeInfo(xmlWriter, objectType, declaredType);
                }
            }
            else if (declaredType.IsArray)//Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item 
            {
                // A call to OnHandleIsReference is not necessary here -- arrays cannot be IsReference 
                dataContract = GetDataContract(objectTypeHandle, objectType); 
                WriteClrTypeInfo(xmlWriter, dataContract);
                dataContract = GetDataContract(declaredTypeHandle, declaredType); 
            }
            else
            {
                dataContract = GetDataContract(objectTypeHandle, objectType); 
                if (OnHandleIsReference(xmlWriter, dataContract, obj))
                    return; 
                if (!WriteClrTypeInfo(xmlWriter, dataContract)) 
                {
                    DataContract declaredTypeContract = (declaredTypeID >= 0) 
                        ? GetDataContract(declaredTypeID, declaredTypeHandle)
                        : GetDataContract(declaredTypeHandle, declaredType);
                    verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, declaredTypeContract);
                } 
            }
 
            SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, declaredTypeHandle, declaredType); 
        }
 
        internal bool OnHandleIsReference(XmlWriterDelegator xmlWriter, DataContract contract, object obj)
        {
            if (preserveObjectReferences || !contract.IsReference || isGetOnlyCollection)
            { 
                return false;
            } 
 
            bool isNew = true;
            int objectId = SerializedObjects.GetId(obj, ref isNew); 
            byValObjectsInScope.EnsureSetAsIsReference(obj);
            if (isNew)
            {
                xmlWriter.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.IdLocalName, 
                                            DictionaryGlobals.SerializationNamespace, string.Format(CultureInfo.InvariantCulture, "{0}{1}", "i", objectId));
                return false; 
            } 
            else
            { 
                xmlWriter.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.RefLocalName, DictionaryGlobals.SerializationNamespace, string.Format(CultureInfo.InvariantCulture, "{0}{1}", "i", objectId));
                return true;
            }
        } 

        protected void SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, bool verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) 
        { 
            bool knownTypesAddedInCurrentScope = false;
            if (dataContract.KnownDataContracts != null) 
            {
                scopedKnownTypes.Push(dataContract.KnownDataContracts);
                knownTypesAddedInCurrentScope = true;
            } 

            if (verifyKnownType) 
            { 
                if (!IsKnownType(dataContract, declaredType))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.DcTypeNotFoundOnSerialize, DataContract.GetClrTypeFullName(dataContract.UnderlyingType), dataContract.StableName.Name, dataContract.StableName.Namespace)));
                }
            }
            WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle); 

            if (knownTypesAddedInCurrentScope) 
            { 
                scopedKnownTypes.Pop();
            } 
        }

        internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, DataContract dataContract)
        { 
            return false;
        } 
 
        internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, string clrTypeName, string clrAssemblyName)
        { 
            return false;
        }

        internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, SerializationInfo serInfo) 
        {
            return false; 
        } 

        public virtual void WriteAnyType(XmlWriterDelegator xmlWriter, object value) 
        {
            xmlWriter.WriteAnyType(value);
        }
 
        public virtual void WriteString(XmlWriterDelegator xmlWriter, string value)
        { 
            xmlWriter.WriteString(value); 
        }
        public virtual void WriteString(XmlWriterDelegator xmlWriter, string value, XmlDictionaryString name, XmlDictionaryString ns) 
        {
            if (value == null)
                WriteNull(xmlWriter, typeof(string), true/*isMemberTypeSerializable*/, name, ns);
            else 
            {
                xmlWriter.WriteStartElementPrimitive(name, ns); 
                xmlWriter.WriteString(value); 
                xmlWriter.WriteEndElementPrimitive();
            } 
        }

        public virtual void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value)
        { 
            xmlWriter.WriteBase64(value);
        } 
        public virtual void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value, XmlDictionaryString name, XmlDictionaryString ns) 
        {
            if (value == null) 
                WriteNull(xmlWriter, typeof(byte[]), true/*isMemberTypeSerializable*/, name, ns);
            else
            {
                xmlWriter.WriteStartElementPrimitive(name, ns); 
                xmlWriter.WriteBase64(value);
                xmlWriter.WriteEndElementPrimitive(); 
            } 
        }
 
        public virtual void WriteUri(XmlWriterDelegator xmlWriter, Uri value)
        {
            xmlWriter.WriteUri(value);
        } 
        public virtual void WriteUri(XmlWriterDelegator xmlWriter, Uri value, XmlDictionaryString name, XmlDictionaryString ns)
        { 
            if (value == null) 
                WriteNull(xmlWriter, typeof(Uri), true/*isMemberTypeSerializable*/, name, ns);
            else 
            {
                xmlWriter.WriteStartElementPrimitive(name, ns);
                xmlWriter.WriteUri(value);
                xmlWriter.WriteEndElementPrimitive(); 
            }
        } 
 
        public virtual void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value)
        { 
            xmlWriter.WriteQName(value);
        }
        public virtual void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value, XmlDictionaryString name, XmlDictionaryString ns)
        { 
            if (value == null)
                WriteNull(xmlWriter, typeof(XmlQualifiedName), true/*isMemberTypeSerializable*/, name, ns); 
            else 
            {
                if (ns != null && ns.Value != null && ns.Value.Length > 0) 
                    xmlWriter.WriteStartElement(Globals.ElementPrefix, name, ns);
                else
                    xmlWriter.WriteStartElement(name, ns);
                xmlWriter.WriteQName(value); 
                xmlWriter.WriteEndElement();
            } 
        } 

        internal void HandleGraphAtTopLevel(XmlWriterDelegator writer, object obj, DataContract contract) 
        {
            writer.WriteXmlnsAttribute(Globals.XsiPrefix, DictionaryGlobals.SchemaInstanceNamespace);
            if (contract.IsISerializable)
                writer.WriteXmlnsAttribute(Globals.XsdPrefix, DictionaryGlobals.SchemaNamespace); 
            OnHandleReference(writer, obj, true /*canContainReferences*/);
        } 
 
        internal virtual bool OnHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference)
        { 
            if (xmlWriter.depth < depthToCheckCyclicReference)
                return false;
            if (canContainCyclicReference)
            { 
                if (byValObjectsInScope.Count == 0 && DiagnosticUtility.ShouldTraceWarning)
                { 
                    TraceUtility.Trace(TraceEventType.Warning, TraceCode.ObjectWithLargeDepth, SR.GetString(SR.TraceCodeObjectWithLargeDepth)); 
                }
                if (byValObjectsInScope.Contains(obj)) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.CannotSerializeObjectWithCycles, DataContract.GetClrTypeFullName(obj.GetType()))));
                byValObjectsInScope.Push(obj);
            }
            return false; 
        }
 
        internal virtual void OnEndHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference) 
        {
            if (xmlWriter.depth < depthToCheckCyclicReference) 
                return;
            if (canContainCyclicReference)
            {
                byValObjectsInScope.Pop(obj); 
            }
        } 
 
        public void WriteNull(XmlWriterDelegator xmlWriter, Type memberType, bool isMemberTypeSerializable)
        { 
            CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
            WriteNull(xmlWriter);
        }
 
        internal void WriteNull(XmlWriterDelegator xmlWriter, Type memberType, bool isMemberTypeSerializable, XmlDictionaryString name, XmlDictionaryString ns)
        { 
            xmlWriter.WriteStartElement(name, ns); 
            WriteNull(xmlWriter, memberType, isMemberTypeSerializable);
            xmlWriter.WriteEndElement(); 
        }

        public void IncrementArrayCount(XmlWriterDelegator xmlWriter, Array array)
        { 
            IncrementCollectionCount(xmlWriter, array.GetLength(0));
        } 
 
        public void IncrementCollectionCount(XmlWriterDelegator xmlWriter, ICollection collection)
        { 
            IncrementCollectionCount(xmlWriter, collection.Count);
        }

        public void IncrementCollectionCountGeneric(XmlWriterDelegator xmlWriter, ICollection collection) 
        {
            IncrementCollectionCount(xmlWriter, collection.Count); 
        } 

        void IncrementCollectionCount(XmlWriterDelegator xmlWriter, int size) 
        {
            IncrementItemCount(size);
            WriteArraySize(xmlWriter, size);
        } 

        internal virtual void WriteArraySize(XmlWriterDelegator xmlWriter, int size) 
        { 
        }
 
        public static T GetDefaultValue()
        {
            return default(T);
        } 

        public static T GetNullableValue(Nullable value)  where T : struct 
        { 
            // value.Value will throw if hasValue is false
            return value.Value; 
        }

        public static void ThrowRequiredMemberMustBeEmitted(string memberName, Type type)
        { 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.RequiredMemberMustBeEmitted, memberName, type.FullName)));
        } 
 
        public static bool GetHasValue(Nullable value)  where T : struct
        { 
            return value.HasValue;
        }

        internal void WriteIXmlSerializable(XmlWriterDelegator xmlWriter, object obj) 
        {
            if (xmlSerializableWriter == null) 
                xmlSerializableWriter = new XmlSerializableWriter(); 
            WriteIXmlSerializable(xmlWriter, obj, xmlSerializableWriter);
        } 

        internal static void WriteRootIXmlSerializable(XmlWriterDelegator xmlWriter, object obj)
        {
            WriteIXmlSerializable(xmlWriter, obj, new XmlSerializableWriter()); 
        }
 
        static void WriteIXmlSerializable(XmlWriterDelegator xmlWriter, object obj, XmlSerializableWriter xmlSerializableWriter) 
        {
            xmlSerializableWriter.BeginWrite(xmlWriter.Writer, obj); 
            IXmlSerializable xmlSerializable = obj as IXmlSerializable;
            if (xmlSerializable != null)
                xmlSerializable.WriteXml(xmlSerializableWriter);
            else 
            {
                XmlElement xmlElement = obj as XmlElement; 
                if (xmlElement != null) 
                    xmlElement.WriteTo(xmlSerializableWriter);
                else 
                {
                    XmlNode[] xmlNodes = obj as XmlNode[];
                    if (xmlNodes != null)
                        foreach (XmlNode xmlNode in xmlNodes) 
                            xmlNode.WriteTo(xmlSerializableWriter);
                    else 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnknownXmlType, DataContract.GetClrTypeFullName(obj.GetType())))); 
                }
            } 
            xmlSerializableWriter.EndWrite();
        }

        [Fx.Tag.SecurityNote(Critical = "Calls the critical methods of ISerializable", Safe = "Demands for FullTrust")] 
        [SecuritySafeCritical]
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 
        [MethodImpl(MethodImplOptions.NoInlining)] 
        void GetObjectData(ISerializable obj, SerializationInfo serInfo, StreamingContext context)
        { 
            obj.GetObjectData(serInfo, context);
        }

        public void WriteISerializable(XmlWriterDelegator xmlWriter, ISerializable obj) 

        { 
            Type objType = obj.GetType(); 
            SerializationInfo serInfo = new SerializationInfo(objType, XmlObjectSerializer.FormatterConverter);
            GetObjectData(obj, serInfo, GetStreamingContext()); 
            WriteSerializationInfo(xmlWriter, objType, serInfo);
        }

        internal void WriteSerializationInfo(XmlWriterDelegator xmlWriter, Type objType, SerializationInfo serInfo) 
        {
            if (DataContract.GetClrTypeFullName(objType) != serInfo.FullTypeName) 
            { 
                if (DataContractResolver != null)
                { 
                    XmlDictionaryString typeName, typeNs;
                    if (ResolveType(serInfo.ObjectType, objType, out typeName, out typeNs))
                    {
                        xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, typeName, typeNs); 
                    }
                } 
                else 
                {
                    string typeName, typeNs; 
                    DataContract.GetDefaultStableName(serInfo.FullTypeName, out typeName, out typeNs);
                    xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(typeName), DataContract.GetClrTypeString(typeNs));
                }
            } 

            WriteClrTypeInfo(xmlWriter, objType, serInfo); 
            IncrementItemCount(serInfo.MemberCount); 
            foreach (SerializationEntry serEntry in serInfo)
            { 
                XmlDictionaryString name = DataContract.GetClrTypeString(DataContract.EncodeLocalName(serEntry.Name));
                xmlWriter.WriteStartElement(name, DictionaryGlobals.EmptyString);
                object obj = serEntry.Value;
                if (obj == null) 
                    WriteNull(xmlWriter);
                else 
                    InternalSerializeReference(xmlWriter, obj, false /*isDeclaredType*/, false /*writeXsiType*/, -1, Globals.TypeOfObject.TypeHandle); 
                xmlWriter.WriteEndElement();
            } 
        }

        public void WriteExtensionData(XmlWriterDelegator xmlWriter, ExtensionDataObject extensionData, int memberIndex)
        { 
            if (IgnoreExtensionDataObject || extensionData == null)
                return; 
 
            IList members = extensionData.Members;
            if (members != null) 
            {
                for (int i = 0; i < extensionData.Members.Count; i++)
                {
                    ExtensionDataMember member = extensionData.Members[i]; 
                    if (member.MemberIndex == memberIndex)
                    { 
                        WriteExtensionDataMember(xmlWriter, member); 
                    }
                } 
            }
        }

        void WriteExtensionDataMember(XmlWriterDelegator xmlWriter, ExtensionDataMember member) 
        {
            xmlWriter.WriteStartElement(member.Name, member.Namespace); 
            IDataNode dataNode = member.Value; 
            WriteExtensionDataValue(xmlWriter, dataNode);
            xmlWriter.WriteEndElement(); 
        }

        internal virtual void WriteExtensionDataTypeInfo(XmlWriterDelegator xmlWriter, IDataNode dataNode)
        { 
            if (dataNode.DataContractName != null)
                WriteTypeInfo(xmlWriter, dataNode.DataContractName, dataNode.DataContractNamespace); 
 
            WriteClrTypeInfo(xmlWriter, dataNode.DataType, dataNode.ClrTypeName, dataNode.ClrAssemblyName);
        } 

        internal void WriteExtensionDataValue(XmlWriterDelegator xmlWriter, IDataNode dataNode)
        {
            IncrementItemCount(1); 
            if (dataNode == null)
            { 
                WriteNull(xmlWriter); 
                return;
            } 

            if (dataNode.PreservesReferences
                && OnHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/))
                return; 

            Type dataType = dataNode.DataType; 
            if (dataType == Globals.TypeOfClassDataNode) 
                WriteExtensionClassData(xmlWriter, (ClassDataNode)dataNode);
            else if (dataType == Globals.TypeOfCollectionDataNode) 
                WriteExtensionCollectionData(xmlWriter, (CollectionDataNode)dataNode);
            else if (dataType == Globals.TypeOfXmlDataNode)
                WriteExtensionXmlData(xmlWriter, (XmlDataNode)dataNode);
            else if (dataType == Globals.TypeOfISerializableDataNode) 
                WriteExtensionISerializableData(xmlWriter, (ISerializableDataNode)dataNode);
            else 
            { 
                WriteExtensionDataTypeInfo(xmlWriter, dataNode);
 
                if (dataType == Globals.TypeOfObject)
                {
                    // NOTE: serialize value in DataNode since it may contain non-primitive
                    // deserialized object (ex. empty class) 
                    object o = dataNode.Value;
                    if (o != null) 
                        InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, o.GetType().TypeHandle); 
                }
                else 
                    xmlWriter.WriteExtensionData(dataNode);
            }
            if (dataNode.PreservesReferences)
                OnEndHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true  /*canContainCyclicReference*/); 
        }
 
        internal bool TryWriteDeserializedExtensionData(XmlWriterDelegator xmlWriter, IDataNode dataNode) 
        {
            object o = dataNode.Value; 
            if (o == null)
                return false;

            Type declaredType = (dataNode.DataContractName == null) ? o.GetType() : Globals.TypeOfObject; 
            InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, declaredType.TypeHandle);
            return true; 
        } 

        void WriteExtensionClassData(XmlWriterDelegator xmlWriter, ClassDataNode dataNode) 
        {
            if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
            {
                WriteExtensionDataTypeInfo(xmlWriter, dataNode); 

                IList members = dataNode.Members; 
                if (members != null) 
                {
                    for (int i = 0; i < members.Count; i++) 
                    {
                        WriteExtensionDataMember(xmlWriter, members[i]);
                    }
                } 
            }
        } 
 
        void WriteExtensionCollectionData(XmlWriterDelegator xmlWriter, CollectionDataNode dataNode)
        { 
            if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
            {
                WriteExtensionDataTypeInfo(xmlWriter, dataNode);
 
                WriteArraySize(xmlWriter, dataNode.Size);
 
                IList items = dataNode.Items; 
                if (items != null)
                { 
                    for (int i = 0; i < items.Count; i++)
                    {
                        xmlWriter.WriteStartElement(dataNode.ItemName, dataNode.ItemNamespace);
                        WriteExtensionDataValue(xmlWriter, items[i]); 
                        xmlWriter.WriteEndElement();
                    } 
                } 
            }
        } 

        void WriteExtensionISerializableData(XmlWriterDelegator xmlWriter, ISerializableDataNode dataNode)
        {
            if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode)) 
            {
                WriteExtensionDataTypeInfo(xmlWriter, dataNode); 
 
                if (dataNode.FactoryTypeName != null)
                    xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, dataNode.FactoryTypeName, dataNode.FactoryTypeNamespace); 

                IList members = dataNode.Members;
                if (members != null)
                { 
                    for (int i = 0; i < members.Count; i++)
                    { 
                        ISerializableDataMember member = members[i]; 
                        xmlWriter.WriteStartElement(member.Name, String.Empty);
                        WriteExtensionDataValue(xmlWriter, member.Value); 
                        xmlWriter.WriteEndElement();
                    }
                }
            } 
        }
 
        void WriteExtensionXmlData(XmlWriterDelegator xmlWriter, XmlDataNode dataNode) 
        {
            if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode)) 
            {
                IList xmlAttributes = dataNode.XmlAttributes;
                if (xmlAttributes != null)
                { 
                    foreach (XmlAttribute attribute in xmlAttributes)
                        attribute.WriteTo(xmlWriter.Writer); 
                } 
                WriteExtensionDataTypeInfo(xmlWriter, dataNode);
 
                IList xmlChildNodes = dataNode.XmlChildNodes;
                if (xmlChildNodes != null)
                {
                    foreach (XmlNode node in xmlChildNodes) 
                        node.WriteTo(xmlWriter.Writer);
                } 
            } 
        }
 
        protected virtual void WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
        {
            dataContract.WriteXmlValue(xmlWriter, obj, this);
        } 

        protected virtual void WriteNull(XmlWriterDelegator xmlWriter) 
        { 
            XmlObjectSerializer.WriteNull(xmlWriter);
        } 

        void WriteResolvedTypeInfo(XmlWriterDelegator writer, Type objectType, Type declaredType)
        {
            XmlDictionaryString typeName, typeNamespace; 
            if (ResolveType(objectType, declaredType, out typeName, out typeNamespace))
            { 
                WriteTypeInfo(writer, typeName, typeNamespace); 
            }
        } 

        bool ResolveType(Type objectType, Type declaredType, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
        {
            if (!DataContractResolver.TryResolveType(objectType, declaredType, KnownTypeResolver, out typeName, out typeNamespace)) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedFalse, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType)))); 
            } 
            if (typeName == null)
            { 
                if (typeNamespace == null)
                {
                    return false;
                } 
                else
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType)))); 
                }
            } 
            if (typeNamespace == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
            } 
            return true;
        } 
 
        protected virtual bool WriteTypeInfo(XmlWriterDelegator writer, DataContract contract, DataContract declaredContract)
        { 
            if (!XmlObjectSerializer.IsContractDeclared(contract, declaredContract))
            {
                if (DataContractResolver == null)
                { 
                    WriteTypeInfo(writer, contract.Name, contract.Namespace);
                    return true; 
                } 
                else
                { 
                    WriteResolvedTypeInfo(writer, contract.OriginalUnderlyingType, declaredContract.OriginalUnderlyingType);
                    return false;
                }
            } 
            return false;
        } 
 
        protected virtual void WriteTypeInfo(XmlWriterDelegator writer, string dataContractName, string dataContractNamespace)
        { 
            writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace);
        }

        protected virtual void WriteTypeInfo(XmlWriterDelegator writer, XmlDictionaryString dataContractName, XmlDictionaryString dataContractNamespace) 
        {
            writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace); 
        } 
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime.Serialization 
{
    using System; 
    using System.Collections; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Xml; 
    using System.Collections.Generic;
    using System.Xml.Serialization; 
    using System.ServiceModel.Diagnostics; 
    using System.Security;
    using System.Security.Permissions; 
    using System.Runtime.CompilerServices;
    using System.Runtime.Serialization.Diagnostics;

#if USE_REFEMIT 
    public class XmlObjectSerializerWriteContext : XmlObjectSerializerContext
#else 
    internal class XmlObjectSerializerWriteContext : XmlObjectSerializerContext 
#endif
    { 
        ObjectReferenceStack byValObjectsInScope = new ObjectReferenceStack();
        XmlSerializableWriter xmlSerializableWriter;
        const int depthToCheckCyclicReference = 512;
        protected bool preserveObjectReferences; 
        ObjectToIdCache serializedObjects;
        bool isGetOnlyCollection; 
 
        internal static XmlObjectSerializerWriteContext CreateContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver)
        { 
            return (serializer.PreserveObjectReferences || serializer.DataContractSurrogate != null)
                ? new XmlObjectSerializerWriteContextComplex(serializer, rootTypeDataContract, dataContractResolver)
                : new XmlObjectSerializerWriteContext(serializer, rootTypeDataContract, dataContractResolver);
        } 

        internal static XmlObjectSerializerWriteContext CreateContext(NetDataContractSerializer serializer, Hashtable surrogateDataContracts) 
        { 
            return new XmlObjectSerializerWriteContextComplex(serializer, surrogateDataContracts);
        } 

        protected XmlObjectSerializerWriteContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver resolver)
            : base(serializer, rootTypeDataContract, resolver)
        { 
        }
 
        protected XmlObjectSerializerWriteContext(NetDataContractSerializer serializer) 
            : base(serializer)
        { 
        }

        internal XmlObjectSerializerWriteContext(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject)
            : base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject) 
        {
        } 
 
#if USE_REFEMIT
        internal ObjectToIdCache SerializedObjects 
#else
        protected ObjectToIdCache SerializedObjects
#endif
        { 
            get
            { 
                if (serializedObjects == null) 
                    serializedObjects = new ObjectToIdCache();
                return serializedObjects; 
            }
        }

        internal override bool IsGetOnlyCollection 
        {
            get { return this.isGetOnlyCollection; } 
            set { this.isGetOnlyCollection = value; } 
        }
 
#if USE_REFEMIT
        public void StoreIsGetOnlyCollection()
#else
        internal void StoreIsGetOnlyCollection() 
#endif
        { 
            this.isGetOnlyCollection = true; 
        }
 
        public void InternalSerializeReference(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
        {
            if (!OnHandleReference(xmlWriter, obj, true /*canContainCyclicReference*/))
                InternalSerialize(xmlWriter, obj, isDeclaredType, writeXsiType, declaredTypeID, declaredTypeHandle); 
            OnEndHandleReference(xmlWriter, obj, true /*canContainCyclicReference*/);
        } 
 
        public virtual void InternalSerialize(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
        { 
            if (writeXsiType)
            {
                Type declaredType = Globals.TypeOfObject;
                SerializeWithXsiType(xmlWriter, obj, Type.GetTypeHandle(obj), null/*type*/, -1, declaredType.TypeHandle, declaredType); 
            }
            else if (isDeclaredType) 
            { 
                DataContract contract = GetDataContract(declaredTypeID, declaredTypeHandle);
                SerializeWithoutXsiType(contract, xmlWriter, obj, declaredTypeHandle); 
            }
            else
            {
                RuntimeTypeHandle objTypeHandle = Type.GetTypeHandle(obj); 
                if (declaredTypeHandle.Equals(objTypeHandle))
                { 
                    DataContract dataContract = (declaredTypeID >= 0) 
                        ? GetDataContract(declaredTypeID, declaredTypeHandle)
                        : GetDataContract(declaredTypeHandle, null /*type*/); 
                    SerializeWithoutXsiType(dataContract, xmlWriter, obj, declaredTypeHandle);
                }
                else
                { 
                    SerializeWithXsiType(xmlWriter, obj, objTypeHandle, null /*type*/, declaredTypeID, declaredTypeHandle, Type.GetTypeFromHandle(declaredTypeHandle));
                } 
            } 
        }
 
        internal void SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
        {
            if (OnHandleIsReference(xmlWriter, dataContract, obj))
                return; 
            if (dataContract.KnownDataContracts != null)
            { 
                scopedKnownTypes.Push(dataContract.KnownDataContracts); 
                WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle);
                scopedKnownTypes.Pop(); 
            }
            else
            {
                WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle); 
            }
        } 
 
        internal virtual void SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType)
        { 
            bool verifyKnownType = false;
            Type declaredType = rootTypeDataContract.OriginalUnderlyingType;

            if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType)) 
            {
                if (DataContractResolver != null) 
                { 
                    WriteResolvedTypeInfo(xmlWriter, graphType, declaredType);
                } 
            }
            else if (!declaredType.IsArray) //Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item
            {
                verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, rootTypeDataContract); 
            }
            SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, originalDeclaredTypeHandle, declaredType); 
        } 

        protected virtual void SerializeWithXsiType(XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) 
        {
            DataContract dataContract;
            bool verifyKnownType = false;
            if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType)) 
            {
                dataContract = GetDataContractSkipValidation(DataContract.GetId(objectTypeHandle), objectTypeHandle, objectType); 
                if (OnHandleIsReference(xmlWriter, dataContract, obj)) 
                    return;
                if (this.Mode == SerializationMode.SharedType && dataContract.IsValidContract(this.Mode)) 
                    dataContract = dataContract.GetValidContract(this.Mode);
                else
                    dataContract = GetDataContract(declaredTypeHandle, declaredType);
                if (!WriteClrTypeInfo(xmlWriter, dataContract) && DataContractResolver != null) 
                {
                    if (objectType == null) 
                    { 
                        objectType = Type.GetTypeFromHandle(objectTypeHandle);
                    } 
                    WriteResolvedTypeInfo(xmlWriter, objectType, declaredType);
                }
            }
            else if (declaredType.IsArray)//Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item 
            {
                // A call to OnHandleIsReference is not necessary here -- arrays cannot be IsReference 
                dataContract = GetDataContract(objectTypeHandle, objectType); 
                WriteClrTypeInfo(xmlWriter, dataContract);
                dataContract = GetDataContract(declaredTypeHandle, declaredType); 
            }
            else
            {
                dataContract = GetDataContract(objectTypeHandle, objectType); 
                if (OnHandleIsReference(xmlWriter, dataContract, obj))
                    return; 
                if (!WriteClrTypeInfo(xmlWriter, dataContract)) 
                {
                    DataContract declaredTypeContract = (declaredTypeID >= 0) 
                        ? GetDataContract(declaredTypeID, declaredTypeHandle)
                        : GetDataContract(declaredTypeHandle, declaredType);
                    verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, declaredTypeContract);
                } 
            }
 
            SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, declaredTypeHandle, declaredType); 
        }
 
        internal bool OnHandleIsReference(XmlWriterDelegator xmlWriter, DataContract contract, object obj)
        {
            if (preserveObjectReferences || !contract.IsReference || isGetOnlyCollection)
            { 
                return false;
            } 
 
            bool isNew = true;
            int objectId = SerializedObjects.GetId(obj, ref isNew); 
            byValObjectsInScope.EnsureSetAsIsReference(obj);
            if (isNew)
            {
                xmlWriter.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.IdLocalName, 
                                            DictionaryGlobals.SerializationNamespace, string.Format(CultureInfo.InvariantCulture, "{0}{1}", "i", objectId));
                return false; 
            } 
            else
            { 
                xmlWriter.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.RefLocalName, DictionaryGlobals.SerializationNamespace, string.Format(CultureInfo.InvariantCulture, "{0}{1}", "i", objectId));
                return true;
            }
        } 

        protected void SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, bool verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) 
        { 
            bool knownTypesAddedInCurrentScope = false;
            if (dataContract.KnownDataContracts != null) 
            {
                scopedKnownTypes.Push(dataContract.KnownDataContracts);
                knownTypesAddedInCurrentScope = true;
            } 

            if (verifyKnownType) 
            { 
                if (!IsKnownType(dataContract, declaredType))
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.DcTypeNotFoundOnSerialize, DataContract.GetClrTypeFullName(dataContract.UnderlyingType), dataContract.StableName.Name, dataContract.StableName.Namespace)));
                }
            }
            WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle); 

            if (knownTypesAddedInCurrentScope) 
            { 
                scopedKnownTypes.Pop();
            } 
        }

        internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, DataContract dataContract)
        { 
            return false;
        } 
 
        internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, string clrTypeName, string clrAssemblyName)
        { 
            return false;
        }

        internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, SerializationInfo serInfo) 
        {
            return false; 
        } 

        public virtual void WriteAnyType(XmlWriterDelegator xmlWriter, object value) 
        {
            xmlWriter.WriteAnyType(value);
        }
 
        public virtual void WriteString(XmlWriterDelegator xmlWriter, string value)
        { 
            xmlWriter.WriteString(value); 
        }
        public virtual void WriteString(XmlWriterDelegator xmlWriter, string value, XmlDictionaryString name, XmlDictionaryString ns) 
        {
            if (value == null)
                WriteNull(xmlWriter, typeof(string), true/*isMemberTypeSerializable*/, name, ns);
            else 
            {
                xmlWriter.WriteStartElementPrimitive(name, ns); 
                xmlWriter.WriteString(value); 
                xmlWriter.WriteEndElementPrimitive();
            } 
        }

        public virtual void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value)
        { 
            xmlWriter.WriteBase64(value);
        } 
        public virtual void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value, XmlDictionaryString name, XmlDictionaryString ns) 
        {
            if (value == null) 
                WriteNull(xmlWriter, typeof(byte[]), true/*isMemberTypeSerializable*/, name, ns);
            else
            {
                xmlWriter.WriteStartElementPrimitive(name, ns); 
                xmlWriter.WriteBase64(value);
                xmlWriter.WriteEndElementPrimitive(); 
            } 
        }
 
        public virtual void WriteUri(XmlWriterDelegator xmlWriter, Uri value)
        {
            xmlWriter.WriteUri(value);
        } 
        public virtual void WriteUri(XmlWriterDelegator xmlWriter, Uri value, XmlDictionaryString name, XmlDictionaryString ns)
        { 
            if (value == null) 
                WriteNull(xmlWriter, typeof(Uri), true/*isMemberTypeSerializable*/, name, ns);
            else 
            {
                xmlWriter.WriteStartElementPrimitive(name, ns);
                xmlWriter.WriteUri(value);
                xmlWriter.WriteEndElementPrimitive(); 
            }
        } 
 
        public virtual void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value)
        { 
            xmlWriter.WriteQName(value);
        }
        public virtual void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value, XmlDictionaryString name, XmlDictionaryString ns)
        { 
            if (value == null)
                WriteNull(xmlWriter, typeof(XmlQualifiedName), true/*isMemberTypeSerializable*/, name, ns); 
            else 
            {
                if (ns != null && ns.Value != null && ns.Value.Length > 0) 
                    xmlWriter.WriteStartElement(Globals.ElementPrefix, name, ns);
                else
                    xmlWriter.WriteStartElement(name, ns);
                xmlWriter.WriteQName(value); 
                xmlWriter.WriteEndElement();
            } 
        } 

        internal void HandleGraphAtTopLevel(XmlWriterDelegator writer, object obj, DataContract contract) 
        {
            writer.WriteXmlnsAttribute(Globals.XsiPrefix, DictionaryGlobals.SchemaInstanceNamespace);
            if (contract.IsISerializable)
                writer.WriteXmlnsAttribute(Globals.XsdPrefix, DictionaryGlobals.SchemaNamespace); 
            OnHandleReference(writer, obj, true /*canContainReferences*/);
        } 
 
        internal virtual bool OnHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference)
        { 
            if (xmlWriter.depth < depthToCheckCyclicReference)
                return false;
            if (canContainCyclicReference)
            { 
                if (byValObjectsInScope.Count == 0 && DiagnosticUtility.ShouldTraceWarning)
                { 
                    TraceUtility.Trace(TraceEventType.Warning, TraceCode.ObjectWithLargeDepth, SR.GetString(SR.TraceCodeObjectWithLargeDepth)); 
                }
                if (byValObjectsInScope.Contains(obj)) 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.CannotSerializeObjectWithCycles, DataContract.GetClrTypeFullName(obj.GetType()))));
                byValObjectsInScope.Push(obj);
            }
            return false; 
        }
 
        internal virtual void OnEndHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference) 
        {
            if (xmlWriter.depth < depthToCheckCyclicReference) 
                return;
            if (canContainCyclicReference)
            {
                byValObjectsInScope.Pop(obj); 
            }
        } 
 
        public void WriteNull(XmlWriterDelegator xmlWriter, Type memberType, bool isMemberTypeSerializable)
        { 
            CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
            WriteNull(xmlWriter);
        }
 
        internal void WriteNull(XmlWriterDelegator xmlWriter, Type memberType, bool isMemberTypeSerializable, XmlDictionaryString name, XmlDictionaryString ns)
        { 
            xmlWriter.WriteStartElement(name, ns); 
            WriteNull(xmlWriter, memberType, isMemberTypeSerializable);
            xmlWriter.WriteEndElement(); 
        }

        public void IncrementArrayCount(XmlWriterDelegator xmlWriter, Array array)
        { 
            IncrementCollectionCount(xmlWriter, array.GetLength(0));
        } 
 
        public void IncrementCollectionCount(XmlWriterDelegator xmlWriter, ICollection collection)
        { 
            IncrementCollectionCount(xmlWriter, collection.Count);
        }

        public void IncrementCollectionCountGeneric(XmlWriterDelegator xmlWriter, ICollection collection) 
        {
            IncrementCollectionCount(xmlWriter, collection.Count); 
        } 

        void IncrementCollectionCount(XmlWriterDelegator xmlWriter, int size) 
        {
            IncrementItemCount(size);
            WriteArraySize(xmlWriter, size);
        } 

        internal virtual void WriteArraySize(XmlWriterDelegator xmlWriter, int size) 
        { 
        }
 
        public static T GetDefaultValue()
        {
            return default(T);
        } 

        public static T GetNullableValue(Nullable value)  where T : struct 
        { 
            // value.Value will throw if hasValue is false
            return value.Value; 
        }

        public static void ThrowRequiredMemberMustBeEmitted(string memberName, Type type)
        { 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.RequiredMemberMustBeEmitted, memberName, type.FullName)));
        } 
 
        public static bool GetHasValue(Nullable value)  where T : struct
        { 
            return value.HasValue;
        }

        internal void WriteIXmlSerializable(XmlWriterDelegator xmlWriter, object obj) 
        {
            if (xmlSerializableWriter == null) 
                xmlSerializableWriter = new XmlSerializableWriter(); 
            WriteIXmlSerializable(xmlWriter, obj, xmlSerializableWriter);
        } 

        internal static void WriteRootIXmlSerializable(XmlWriterDelegator xmlWriter, object obj)
        {
            WriteIXmlSerializable(xmlWriter, obj, new XmlSerializableWriter()); 
        }
 
        static void WriteIXmlSerializable(XmlWriterDelegator xmlWriter, object obj, XmlSerializableWriter xmlSerializableWriter) 
        {
            xmlSerializableWriter.BeginWrite(xmlWriter.Writer, obj); 
            IXmlSerializable xmlSerializable = obj as IXmlSerializable;
            if (xmlSerializable != null)
                xmlSerializable.WriteXml(xmlSerializableWriter);
            else 
            {
                XmlElement xmlElement = obj as XmlElement; 
                if (xmlElement != null) 
                    xmlElement.WriteTo(xmlSerializableWriter);
                else 
                {
                    XmlNode[] xmlNodes = obj as XmlNode[];
                    if (xmlNodes != null)
                        foreach (XmlNode xmlNode in xmlNodes) 
                            xmlNode.WriteTo(xmlSerializableWriter);
                    else 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnknownXmlType, DataContract.GetClrTypeFullName(obj.GetType())))); 
                }
            } 
            xmlSerializableWriter.EndWrite();
        }

        [Fx.Tag.SecurityNote(Critical = "Calls the critical methods of ISerializable", Safe = "Demands for FullTrust")] 
        [SecuritySafeCritical]
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 
        [MethodImpl(MethodImplOptions.NoInlining)] 
        void GetObjectData(ISerializable obj, SerializationInfo serInfo, StreamingContext context)
        { 
            obj.GetObjectData(serInfo, context);
        }

        public void WriteISerializable(XmlWriterDelegator xmlWriter, ISerializable obj) 

        { 
            Type objType = obj.GetType(); 
            SerializationInfo serInfo = new SerializationInfo(objType, XmlObjectSerializer.FormatterConverter);
            GetObjectData(obj, serInfo, GetStreamingContext()); 
            WriteSerializationInfo(xmlWriter, objType, serInfo);
        }

        internal void WriteSerializationInfo(XmlWriterDelegator xmlWriter, Type objType, SerializationInfo serInfo) 
        {
            if (DataContract.GetClrTypeFullName(objType) != serInfo.FullTypeName) 
            { 
                if (DataContractResolver != null)
                { 
                    XmlDictionaryString typeName, typeNs;
                    if (ResolveType(serInfo.ObjectType, objType, out typeName, out typeNs))
                    {
                        xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, typeName, typeNs); 
                    }
                } 
                else 
                {
                    string typeName, typeNs; 
                    DataContract.GetDefaultStableName(serInfo.FullTypeName, out typeName, out typeNs);
                    xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(typeName), DataContract.GetClrTypeString(typeNs));
                }
            } 

            WriteClrTypeInfo(xmlWriter, objType, serInfo); 
            IncrementItemCount(serInfo.MemberCount); 
            foreach (SerializationEntry serEntry in serInfo)
            { 
                XmlDictionaryString name = DataContract.GetClrTypeString(DataContract.EncodeLocalName(serEntry.Name));
                xmlWriter.WriteStartElement(name, DictionaryGlobals.EmptyString);
                object obj = serEntry.Value;
                if (obj == null) 
                    WriteNull(xmlWriter);
                else 
                    InternalSerializeReference(xmlWriter, obj, false /*isDeclaredType*/, false /*writeXsiType*/, -1, Globals.TypeOfObject.TypeHandle); 
                xmlWriter.WriteEndElement();
            } 
        }

        public void WriteExtensionData(XmlWriterDelegator xmlWriter, ExtensionDataObject extensionData, int memberIndex)
        { 
            if (IgnoreExtensionDataObject || extensionData == null)
                return; 
 
            IList members = extensionData.Members;
            if (members != null) 
            {
                for (int i = 0; i < extensionData.Members.Count; i++)
                {
                    ExtensionDataMember member = extensionData.Members[i]; 
                    if (member.MemberIndex == memberIndex)
                    { 
                        WriteExtensionDataMember(xmlWriter, member); 
                    }
                } 
            }
        }

        void WriteExtensionDataMember(XmlWriterDelegator xmlWriter, ExtensionDataMember member) 
        {
            xmlWriter.WriteStartElement(member.Name, member.Namespace); 
            IDataNode dataNode = member.Value; 
            WriteExtensionDataValue(xmlWriter, dataNode);
            xmlWriter.WriteEndElement(); 
        }

        internal virtual void WriteExtensionDataTypeInfo(XmlWriterDelegator xmlWriter, IDataNode dataNode)
        { 
            if (dataNode.DataContractName != null)
                WriteTypeInfo(xmlWriter, dataNode.DataContractName, dataNode.DataContractNamespace); 
 
            WriteClrTypeInfo(xmlWriter, dataNode.DataType, dataNode.ClrTypeName, dataNode.ClrAssemblyName);
        } 

        internal void WriteExtensionDataValue(XmlWriterDelegator xmlWriter, IDataNode dataNode)
        {
            IncrementItemCount(1); 
            if (dataNode == null)
            { 
                WriteNull(xmlWriter); 
                return;
            } 

            if (dataNode.PreservesReferences
                && OnHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/))
                return; 

            Type dataType = dataNode.DataType; 
            if (dataType == Globals.TypeOfClassDataNode) 
                WriteExtensionClassData(xmlWriter, (ClassDataNode)dataNode);
            else if (dataType == Globals.TypeOfCollectionDataNode) 
                WriteExtensionCollectionData(xmlWriter, (CollectionDataNode)dataNode);
            else if (dataType == Globals.TypeOfXmlDataNode)
                WriteExtensionXmlData(xmlWriter, (XmlDataNode)dataNode);
            else if (dataType == Globals.TypeOfISerializableDataNode) 
                WriteExtensionISerializableData(xmlWriter, (ISerializableDataNode)dataNode);
            else 
            { 
                WriteExtensionDataTypeInfo(xmlWriter, dataNode);
 
                if (dataType == Globals.TypeOfObject)
                {
                    // NOTE: serialize value in DataNode since it may contain non-primitive
                    // deserialized object (ex. empty class) 
                    object o = dataNode.Value;
                    if (o != null) 
                        InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, o.GetType().TypeHandle); 
                }
                else 
                    xmlWriter.WriteExtensionData(dataNode);
            }
            if (dataNode.PreservesReferences)
                OnEndHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true  /*canContainCyclicReference*/); 
        }
 
        internal bool TryWriteDeserializedExtensionData(XmlWriterDelegator xmlWriter, IDataNode dataNode) 
        {
            object o = dataNode.Value; 
            if (o == null)
                return false;

            Type declaredType = (dataNode.DataContractName == null) ? o.GetType() : Globals.TypeOfObject; 
            InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, declaredType.TypeHandle);
            return true; 
        } 

        void WriteExtensionClassData(XmlWriterDelegator xmlWriter, ClassDataNode dataNode) 
        {
            if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
            {
                WriteExtensionDataTypeInfo(xmlWriter, dataNode); 

                IList members = dataNode.Members; 
                if (members != null) 
                {
                    for (int i = 0; i < members.Count; i++) 
                    {
                        WriteExtensionDataMember(xmlWriter, members[i]);
                    }
                } 
            }
        } 
 
        void WriteExtensionCollectionData(XmlWriterDelegator xmlWriter, CollectionDataNode dataNode)
        { 
            if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
            {
                WriteExtensionDataTypeInfo(xmlWriter, dataNode);
 
                WriteArraySize(xmlWriter, dataNode.Size);
 
                IList items = dataNode.Items; 
                if (items != null)
                { 
                    for (int i = 0; i < items.Count; i++)
                    {
                        xmlWriter.WriteStartElement(dataNode.ItemName, dataNode.ItemNamespace);
                        WriteExtensionDataValue(xmlWriter, items[i]); 
                        xmlWriter.WriteEndElement();
                    } 
                } 
            }
        } 

        void WriteExtensionISerializableData(XmlWriterDelegator xmlWriter, ISerializableDataNode dataNode)
        {
            if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode)) 
            {
                WriteExtensionDataTypeInfo(xmlWriter, dataNode); 
 
                if (dataNode.FactoryTypeName != null)
                    xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, dataNode.FactoryTypeName, dataNode.FactoryTypeNamespace); 

                IList members = dataNode.Members;
                if (members != null)
                { 
                    for (int i = 0; i < members.Count; i++)
                    { 
                        ISerializableDataMember member = members[i]; 
                        xmlWriter.WriteStartElement(member.Name, String.Empty);
                        WriteExtensionDataValue(xmlWriter, member.Value); 
                        xmlWriter.WriteEndElement();
                    }
                }
            } 
        }
 
        void WriteExtensionXmlData(XmlWriterDelegator xmlWriter, XmlDataNode dataNode) 
        {
            if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode)) 
            {
                IList xmlAttributes = dataNode.XmlAttributes;
                if (xmlAttributes != null)
                { 
                    foreach (XmlAttribute attribute in xmlAttributes)
                        attribute.WriteTo(xmlWriter.Writer); 
                } 
                WriteExtensionDataTypeInfo(xmlWriter, dataNode);
 
                IList xmlChildNodes = dataNode.XmlChildNodes;
                if (xmlChildNodes != null)
                {
                    foreach (XmlNode node in xmlChildNodes) 
                        node.WriteTo(xmlWriter.Writer);
                } 
            } 
        }
 
        protected virtual void WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
        {
            dataContract.WriteXmlValue(xmlWriter, obj, this);
        } 

        protected virtual void WriteNull(XmlWriterDelegator xmlWriter) 
        { 
            XmlObjectSerializer.WriteNull(xmlWriter);
        } 

        void WriteResolvedTypeInfo(XmlWriterDelegator writer, Type objectType, Type declaredType)
        {
            XmlDictionaryString typeName, typeNamespace; 
            if (ResolveType(objectType, declaredType, out typeName, out typeNamespace))
            { 
                WriteTypeInfo(writer, typeName, typeNamespace); 
            }
        } 

        bool ResolveType(Type objectType, Type declaredType, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
        {
            if (!DataContractResolver.TryResolveType(objectType, declaredType, KnownTypeResolver, out typeName, out typeNamespace)) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedFalse, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType)))); 
            } 
            if (typeName == null)
            { 
                if (typeNamespace == null)
                {
                    return false;
                } 
                else
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType)))); 
                }
            } 
            if (typeNamespace == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
            } 
            return true;
        } 
 
        protected virtual bool WriteTypeInfo(XmlWriterDelegator writer, DataContract contract, DataContract declaredContract)
        { 
            if (!XmlObjectSerializer.IsContractDeclared(contract, declaredContract))
            {
                if (DataContractResolver == null)
                { 
                    WriteTypeInfo(writer, contract.Name, contract.Namespace);
                    return true; 
                } 
                else
                { 
                    WriteResolvedTypeInfo(writer, contract.OriginalUnderlyingType, declaredContract.OriginalUnderlyingType);
                    return false;
                }
            } 
            return false;
        } 
 
        protected virtual void WriteTypeInfo(XmlWriterDelegator writer, string dataContractName, string dataContractNamespace)
        { 
            writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace);
        }

        protected virtual void WriteTypeInfo(XmlWriterDelegator writer, XmlDictionaryString dataContractName, XmlDictionaryString dataContractNamespace) 
        {
            writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace); 
        } 
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK