XmlObjectSerializerReadContext.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 / XmlObjectSerializerReadContext.cs / 1305376 / XmlObjectSerializerReadContext.cs

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

namespace System.Runtime.Serialization 
{
    using System; 
    using System.Collections; 
    using System.Collections.Generic;
    using System.Diagnostics; 
    using System.Runtime.Diagnostics;
    using System.ServiceModel.Diagnostics;
    using System.Text;
    using System.Xml; 
    using System.Xml.Serialization;
    using System.Runtime.Serialization.Diagnostics; 
 
#if USE_REFEMIT
    public class XmlObjectSerializerReadContext : XmlObjectSerializerContext 
#else
    internal class XmlObjectSerializerReadContext : XmlObjectSerializerContext
#endif
    { 
        internal Attributes attributes;
        HybridObjectCache deserializedObjects; 
        XmlSerializableReader xmlSerializableReader; 
        XmlDocument xmlDocument;
        Attributes attributesInXmlData; 
        XmlReaderDelegator extensionDataReader;
        object getOnlyCollectionValue;
        bool isGetOnlyCollection;
 
        HybridObjectCache DeserializedObjects
        { 
            get 
            {
                if (deserializedObjects == null) 
                    deserializedObjects = new HybridObjectCache();
                return deserializedObjects;
            }
        } 

        XmlDocument Document 
        { 
            get
            { 
                if (xmlDocument == null)
                    xmlDocument = new XmlDocument();
                return xmlDocument;
            } 
        }
 
        internal override bool IsGetOnlyCollection 
        {
            get { return this.isGetOnlyCollection; } 
            set { this.isGetOnlyCollection = value; }
        }

 
#if USE_REFEMIT
        public object GetCollectionMember() 
#else 
        internal object GetCollectionMember()
#endif 
        {
            return this.getOnlyCollectionValue;
        }
 
#if USE_REFEMIT
        public void StoreCollectionMemberInfo(object collectionMember) 
#else 
        internal void StoreCollectionMemberInfo(object collectionMember)
#endif 
        {
            this.getOnlyCollectionValue = collectionMember;
            this.isGetOnlyCollection = true;
        } 

#if USE_REFEMIT 
        public static void ThrowNullValueReturnedForGetOnlyCollectionException(Type type) 
#else
        internal static void ThrowNullValueReturnedForGetOnlyCollectionException(Type type) 
#endif
        {
            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.NullValueReturnedForGetOnlyCollection, DataContract.GetClrTypeFullName(type))));
        } 

#if USE_REFEMIT 
        public static void ThrowArrayExceededSizeException(int arraySize, Type type) 
#else
        internal static void ThrowArrayExceededSizeException(int arraySize, Type type) 
#endif
        {
            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayExceededSize, arraySize, DataContract.GetClrTypeFullName(type))));
        } 

        internal static XmlObjectSerializerReadContext CreateContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver) 
        { 
            return (serializer.PreserveObjectReferences || serializer.DataContractSurrogate != null)
                ? new XmlObjectSerializerReadContextComplex(serializer, rootTypeDataContract, dataContractResolver) 
                : new XmlObjectSerializerReadContext(serializer, rootTypeDataContract, dataContractResolver);
        }

        internal static XmlObjectSerializerReadContext CreateContext(NetDataContractSerializer serializer) 
        {
            return new XmlObjectSerializerReadContextComplex(serializer); 
        } 

        internal XmlObjectSerializerReadContext(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject) 
            : base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject)
        {
        }
 
        internal XmlObjectSerializerReadContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver)
            : base(serializer, rootTypeDataContract, dataContractResolver) 
        { 
            this.attributes = new Attributes();
        } 

        protected XmlObjectSerializerReadContext(NetDataContractSerializer serializer)
            : base(serializer)
        { 
            this.attributes = new Attributes();
        } 
 
        public virtual object InternalDeserialize(XmlReaderDelegator xmlReader, int id, RuntimeTypeHandle declaredTypeHandle, string name, string ns)
        { 
            DataContract dataContract = GetDataContract(id, declaredTypeHandle);
            return InternalDeserialize(xmlReader, name, ns, Type.GetTypeFromHandle(declaredTypeHandle),ref dataContract);
        }
 
        internal virtual object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, string name, string ns)
        { 
            DataContract dataContract = GetDataContract(declaredType); 
            return InternalDeserialize(xmlReader, name, ns, declaredType, ref dataContract);
        } 

        internal virtual object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, string name, string ns)
        {
            if (dataContract == null) 
                GetDataContract(declaredType);
            return InternalDeserialize(xmlReader, name, ns, declaredType, ref dataContract); 
        } 

        protected bool TryHandleNullOrRef(XmlReaderDelegator reader, Type declaredType, string name, string ns, ref object retObj) 
        {
            ReadAttributes(reader);

            if (attributes.Ref != Globals.NewObjectId) 
            {
                if (this.isGetOnlyCollection) 
                { 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsReferenceGetOnlyCollectionsNotSupported, attributes.Ref, DataContract.GetClrTypeFullName(declaredType))));
                } 
                else
                {
                    retObj = GetExistingObject(attributes.Ref, declaredType, name, ns);
                    reader.Skip(); 
                    return true;
                } 
            } 
            else if (attributes.XsiNil)
            { 
                reader.Skip();
                return true;
            }
            return false; 
        }
 
        protected object InternalDeserialize(XmlReaderDelegator reader, string name, string ns, Type declaredType, ref DataContract dataContract) 
        {
            object retObj = null; 
            if (TryHandleNullOrRef(reader, dataContract.UnderlyingType, name, ns, ref retObj))
                return retObj;

            bool knownTypesAddedInCurrentScope = false; 
            if (dataContract.KnownDataContracts != null)
            { 
                scopedKnownTypes.Push(dataContract.KnownDataContracts); 
                knownTypesAddedInCurrentScope = true;
            } 

            if (attributes.XsiTypeName != null)
            {
                dataContract = ResolveDataContractFromKnownTypes(attributes.XsiTypeName, attributes.XsiTypeNamespace, dataContract, declaredType); 
                if (dataContract == null)
                { 
                    if (DataContractResolver == null) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(reader, SR.GetString(SR.DcTypeNotFoundOnDeserialize, attributes.XsiTypeNamespace, attributes.XsiTypeName, reader.NamespaceURI, reader.LocalName)))); 
                    }
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(reader, SR.GetString(SR.DcTypeNotResolvedOnDeserialize, attributes.XsiTypeNamespace, attributes.XsiTypeName, reader.NamespaceURI, reader.LocalName))));
                }
                knownTypesAddedInCurrentScope = ReplaceScopedKnownTypesTop(dataContract.KnownDataContracts, knownTypesAddedInCurrentScope); 
            }
 
            if (dataContract.IsISerializable && attributes.FactoryTypeName != null) 
            {
                DataContract factoryDataContract = ResolveDataContractFromKnownTypes(attributes.FactoryTypeName, attributes.FactoryTypeNamespace, dataContract, declaredType); 
                if (factoryDataContract != null)
                {
                    if (factoryDataContract.IsISerializable)
                    { 
                        dataContract = factoryDataContract;
                        knownTypesAddedInCurrentScope = ReplaceScopedKnownTypesTop(dataContract.KnownDataContracts, knownTypesAddedInCurrentScope); 
                    } 
                    else
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.FactoryTypeNotISerializable, DataContract.GetClrTypeFullName(factoryDataContract.UnderlyingType), DataContract.GetClrTypeFullName(dataContract.UnderlyingType)))); 
                }
                else
                {
                    if (DiagnosticUtility.ShouldTraceWarning) 
                    {
                        Dictionary values = new Dictionary(2); 
                        values["FactoryType"] = attributes.FactoryTypeNamespace + ":" + attributes.FactoryTypeName; 
                        values["ISerializableType"] = dataContract.StableName.Namespace + ":" + dataContract.StableName.Name;
                        TraceUtility.Trace(TraceEventType.Warning, TraceCode.FactoryTypeNotFound, 
                            SR.GetString(SR.TraceCodeFactoryTypeNotFound), new DictionaryTraceRecord(values));
                    }
                }
            } 

            if (knownTypesAddedInCurrentScope) 
            { 
                object obj = ReadDataContractValue(dataContract, reader);
                scopedKnownTypes.Pop(); 
                return obj;
            }
            else
            { 
                return ReadDataContractValue(dataContract, reader);
            } 
        } 

        bool ReplaceScopedKnownTypesTop(Dictionary knownDataContracts, bool knownTypesAddedInCurrentScope) 
        {
            if (knownTypesAddedInCurrentScope)
            {
                scopedKnownTypes.Pop(); 
                knownTypesAddedInCurrentScope = false;
            } 
            if (knownDataContracts != null) 
            {
                scopedKnownTypes.Push(knownDataContracts); 
                knownTypesAddedInCurrentScope = true;
            }
            return knownTypesAddedInCurrentScope;
        } 

        public static bool MoveToNextElement(XmlReaderDelegator xmlReader) 
        { 
            return (xmlReader.MoveToContent() != XmlNodeType.EndElement);
        } 

        public int GetMemberIndex(XmlReaderDelegator xmlReader, XmlDictionaryString[] memberNames, XmlDictionaryString[] memberNamespaces, int memberIndex, ExtensionDataObject extensionData)
        {
            for (int i = memberIndex + 1; i < memberNames.Length; i++) 
            {
                if (xmlReader.IsStartElement(memberNames[i], memberNamespaces[i])) 
                    return i; 
            }
            HandleMemberNotFound(xmlReader, extensionData, memberIndex); 
            return memberNames.Length;
        }

        public int GetMemberIndexWithRequiredMembers(XmlReaderDelegator xmlReader, XmlDictionaryString[] memberNames, XmlDictionaryString[] memberNamespaces, int memberIndex, int requiredIndex, ExtensionDataObject extensionData) 
        {
            for (int i = memberIndex + 1; i < memberNames.Length; i++) 
            { 
                if (xmlReader.IsStartElement(memberNames[i], memberNamespaces[i]))
                { 
                    if (requiredIndex < i)
                        ThrowRequiredMemberMissingException(xmlReader, memberIndex, requiredIndex, memberNames);
                    return i;
                } 
            }
            HandleMemberNotFound(xmlReader, extensionData, memberIndex); 
            return memberNames.Length; 
        }
 
        public static void ThrowRequiredMemberMissingException(XmlReaderDelegator xmlReader, int memberIndex, int requiredIndex, XmlDictionaryString[] memberNames)
        {
            StringBuilder stringBuilder = new StringBuilder();
            if (requiredIndex == memberNames.Length) 
                requiredIndex--;
            for (int i = memberIndex + 1; i <= requiredIndex; i++) 
            { 
                if (stringBuilder.Length != 0)
                    stringBuilder.Append(" | "); 
                stringBuilder.Append(memberNames[i].Value);
            }
            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.GetString(SR.UnexpectedElementExpectingElements, xmlReader.NodeType, xmlReader.LocalName, xmlReader.NamespaceURI, stringBuilder.ToString()))));
        } 

        protected void HandleMemberNotFound(XmlReaderDelegator xmlReader, ExtensionDataObject extensionData, int memberIndex) 
        { 
            xmlReader.MoveToContent();
            if (xmlReader.NodeType != XmlNodeType.Element) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));

            if (IgnoreExtensionDataObject || extensionData == null)
                SkipUnknownElement(xmlReader); 
            else
                HandleUnknownElement(xmlReader, extensionData, memberIndex); 
        } 

        internal void HandleUnknownElement(XmlReaderDelegator xmlReader, ExtensionDataObject extensionData, int memberIndex) 
        {
            if (extensionData.Members == null)
                extensionData.Members = new List();
            extensionData.Members.Add(ReadExtensionDataMember(xmlReader, memberIndex)); 
        }
 
        public void SkipUnknownElement(XmlReaderDelegator xmlReader) 
        {
            ReadAttributes(xmlReader); 
            if (DiagnosticUtility.ShouldTraceVerbose)
            {
                TraceUtility.Trace(TraceEventType.Verbose, TraceCode.ElementIgnored,
                    SR.GetString(SR.TraceCodeElementIgnored), new StringTraceRecord("Element", xmlReader.NamespaceURI + ":" + xmlReader.LocalName)); 
            }
            xmlReader.Skip(); 
        } 

        public string ReadIfNullOrRef(XmlReaderDelegator xmlReader, Type memberType, bool isMemberTypeSerializable) 
        {
            if (attributes.Ref != Globals.NewObjectId)
            {
                CheckIfTypeSerializable(memberType, isMemberTypeSerializable); 
                xmlReader.Skip();
                return attributes.Ref; 
            } 
            else if (attributes.XsiNil)
            { 
                CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
                xmlReader.Skip();
                return Globals.NullObjectId;
            } 
            return Globals.NewObjectId;
        } 
 
#if USE_REFEMIT
        public virtual void ReadAttributes(XmlReaderDelegator xmlReader) 
#else
        internal virtual void ReadAttributes(XmlReaderDelegator xmlReader)
#endif
        { 
            if (attributes == null)
                attributes = new Attributes(); 
            attributes.Read(xmlReader); 
        }
 
        public void ResetAttributes()
        {
            if (attributes != null)
                attributes.Reset(); 
        }
 
        public string GetObjectId() 
        {
            return attributes.Id; 
        }

#if USE_REFEMIT
        public virtual int GetArraySize() 
#else
        internal virtual int GetArraySize() 
#endif 
        {
            return -1; 
        }

        public void AddNewObject(object obj)
        { 
            AddNewObjectWithId(attributes.Id, obj);
        } 
 
        public void AddNewObjectWithId(string id, object obj)
        { 
            if (id != Globals.NewObjectId)
                DeserializedObjects.Add(id, obj);
            if (extensionDataReader != null)
                extensionDataReader.UnderlyingExtensionDataReader.SetDeserializedValue(obj); 
        }
 
        public void ReplaceDeserializedObject(string id, object oldObj, object newObj) 
        {
            if (object.ReferenceEquals(oldObj, newObj)) 
                return;

            if (id != Globals.NewObjectId)
            { 
                // In certain cases (IObjectReference, SerializationSurrogate or DataContractSurrogate),
                // an object can be replaced with a different object once it is deserialized. If the 
                // object happens to be referenced from within itself, that reference needs to be updated 
                // with the new instance. BinaryFormatter supports this by fixing up such references later.
                // These XmlObjectSerializer implementations do not currently support fix-ups. Hence we 
                // throw in such cases to allow us add fix-up support in the future if we need to.
                if (DeserializedObjects.IsObjectReferenced(id))
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.FactoryObjectContainsSelfReference, DataContract.GetClrTypeFullName(oldObj.GetType()), DataContract.GetClrTypeFullName(newObj.GetType()), id)));
                DeserializedObjects.Remove(id); 
                DeserializedObjects.Add(id, newObj);
            } 
            if (extensionDataReader != null) 
                extensionDataReader.UnderlyingExtensionDataReader.SetDeserializedValue(newObj);
        } 

        public object GetExistingObject(string id, Type type, string name, string ns)
        {
            object retObj = DeserializedObjects.GetObject(id); 
            if (retObj == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.DeserializedObjectWithIdNotFound, id))); 
            if (retObj is IDataNode) 
            {
                IDataNode dataNode = (IDataNode)retObj; 
                retObj = (dataNode.Value != null && dataNode.IsFinalValue) ? dataNode.Value : DeserializeFromExtensionData(dataNode, type, name, ns);
            }
            return retObj;
        } 

        object GetExistingObjectOrExtensionData(string id) 
        { 
            object retObj = DeserializedObjects.GetObject(id);
            if (retObj == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.DeserializedObjectWithIdNotFound, id)));
            return retObj;
        }
 
        public object GetRealObject(IObjectReference obj, string id)
        { 
            object realObj = SurrogateDataContract.GetRealObject(obj, this.GetStreamingContext()); 
            // If GetRealObject returns null, it indicates that the object could not resolve itself because
            // it is missing information. This may occur in a case where multiple IObjectReference instances 
            // depend on each other. BinaryFormatter supports this by fixing up the references later. These
            // XmlObjectSerializer implementations do not support fix-ups since the format does not contain
            // forward references. However, we throw for this case since it allows us to add fix-up support
            // in the future if we need to. 
            if (realObj == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.GetRealObjectReturnedNull, DataContract.GetClrTypeFullName(obj.GetType())))); 
            ReplaceDeserializedObject(id, obj, realObj); 
            return realObj;
        } 

        object DeserializeFromExtensionData(IDataNode dataNode, Type type, string name, string ns)
        {
            ExtensionDataReader underlyingExtensionDataReader; 
            if (extensionDataReader == null)
            { 
                underlyingExtensionDataReader = new ExtensionDataReader(this); 
                extensionDataReader = CreateReaderDelegatorForReader(underlyingExtensionDataReader);
            } 
            else
                underlyingExtensionDataReader = extensionDataReader.UnderlyingExtensionDataReader;
            underlyingExtensionDataReader.SetDataNode(dataNode, name, ns);
            object retObj = InternalDeserialize(extensionDataReader, type, name, ns); 
            dataNode.Clear();
            underlyingExtensionDataReader.Reset(); 
            return retObj; 
        }
 
        public static void Read(XmlReaderDelegator xmlReader)
        {
            if (!xmlReader.Read())
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnexpectedEndOfFile))); 
        }
 
        internal static void ParseQualifiedName(string qname, XmlReaderDelegator xmlReader, out string name, out string ns, out string prefix) 
        {
            int colon = qname.IndexOf(':'); 
            prefix = "";
            if (colon >= 0)
                prefix = qname.Substring(0, colon);
            name = qname.Substring(colon + 1); 
            ns = xmlReader.LookupNamespace(prefix);
        } 
 
        public static T[] EnsureArraySize(T[] array, int index)
        { 
            if (array.Length <= index)
            {
                if (index == Int32.MaxValue)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        XmlObjectSerializer.CreateSerializationException( 
                        SR.GetString(SR.MaxArrayLengthExceeded, Int32.MaxValue, 
                        DataContract.GetClrTypeFullName(typeof(T)))));
                } 
                int newSize = (index < Int32.MaxValue / 2) ? index * 2 : Int32.MaxValue;
                T[] newArray = new T[newSize];
                Array.Copy(array, 0, newArray, 0, array.Length);
                array = newArray; 
            }
            return array; 
        } 

        public static T[] TrimArraySize(T[] array, int size) 
        {
            if (size != array.Length)
            {
                T[] newArray = new T[size]; 
                Array.Copy(array, 0, newArray, 0, size);
                array = newArray; 
            } 
            return array;
        } 

        public void CheckEndOfArray(XmlReaderDelegator xmlReader, int arraySize, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
        {
            if (xmlReader.NodeType == XmlNodeType.EndElement) 
                return;
            while (xmlReader.IsStartElement()) 
            { 
                if (xmlReader.IsStartElement(itemName, itemNamespace))
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayExceededSizeAttribute, arraySize, itemName.Value, itemNamespace.Value))); 
                SkipUnknownElement(xmlReader);
            }
            if (xmlReader.NodeType != XmlNodeType.EndElement)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.EndElement, xmlReader)); 
        }
 
        internal object ReadIXmlSerializable(XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, bool isMemberType) 
        {
            if (xmlSerializableReader == null) 
                xmlSerializableReader = new XmlSerializableReader();
            return ReadIXmlSerializable(xmlSerializableReader, xmlReader, xmlDataContract, isMemberType);
        }
 
        internal static object ReadRootIXmlSerializable(XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, bool isMemberType)
        { 
            return ReadIXmlSerializable(new XmlSerializableReader(), xmlReader, xmlDataContract, isMemberType); 
        }
 
        internal static object ReadIXmlSerializable(XmlSerializableReader xmlSerializableReader, XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, bool isMemberType)
        {
            object obj = null;
            xmlSerializableReader.BeginRead(xmlReader); 
            if (isMemberType && !xmlDataContract.HasRoot)
            { 
                xmlReader.Read(); 
                xmlReader.MoveToContent();
            } 
            if (xmlDataContract.UnderlyingType == Globals.TypeOfXmlElement)
            {
                if (!xmlReader.IsStartElement())
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader)); 
                XmlDocument xmlDoc = new XmlDocument();
                obj = (XmlElement)xmlDoc.ReadNode(xmlSerializableReader); 
            } 
            else if (xmlDataContract.UnderlyingType == Globals.TypeOfXmlNodeArray)
            { 
                obj = XmlSerializableServices.ReadNodes(xmlSerializableReader);
            }
            else
            { 
                IXmlSerializable xmlSerializable = xmlDataContract.CreateXmlSerializableDelegate();
                xmlSerializable.ReadXml(xmlSerializableReader); 
                obj = xmlSerializable; 
            }
            xmlSerializableReader.EndRead(); 
            return obj;
        }

        public SerializationInfo ReadSerializationInfo(XmlReaderDelegator xmlReader, Type type) 
        {
            SerializationInfo serInfo = new SerializationInfo(type, XmlObjectSerializer.FormatterConverter); 
            XmlNodeType nodeType; 
            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement)
            { 
                if (nodeType != XmlNodeType.Element)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));

                if (xmlReader.NamespaceURI.Length != 0) 
                {
                    SkipUnknownElement(xmlReader); 
                    continue; 
                }
                string name = XmlConvert.DecodeName(xmlReader.LocalName); 

                IncrementItemCount(1);
                ReadAttributes(xmlReader);
                object value; 
                if (attributes.Ref != Globals.NewObjectId)
                { 
                    xmlReader.Skip(); 
                    value = GetExistingObject(attributes.Ref, null, name, String.Empty);
                } 
                else if (attributes.XsiNil)
                {
                    xmlReader.Skip();
                    value = null; 
                }
                else 
                { 
                    value = InternalDeserialize(xmlReader, Globals.TypeOfObject, name, String.Empty);
                } 

                serInfo.AddValue(name, value);
            }
 
            return serInfo;
        } 
 
        protected virtual DataContract ResolveDataContractFromTypeName()
        { 
            return (attributes.XsiTypeName == null) ? null : ResolveDataContractFromKnownTypes(attributes.XsiTypeName, attributes.XsiTypeNamespace, null /*memberTypeContract*/, null);
        }

        ExtensionDataMember ReadExtensionDataMember(XmlReaderDelegator xmlReader, int memberIndex) 
        {
            ExtensionDataMember member = new ExtensionDataMember(); 
            member.Name = xmlReader.LocalName; 
            member.Namespace = xmlReader.NamespaceURI;
            member.MemberIndex = memberIndex; 
            if (xmlReader.UnderlyingExtensionDataReader != null)
            {
                // no need to re-read extension data structure
                member.Value = xmlReader.UnderlyingExtensionDataReader.GetCurrentNode(); 
            }
            else 
                member.Value = ReadExtensionDataValue(xmlReader); 
            return member;
        } 

        public IDataNode ReadExtensionDataValue(XmlReaderDelegator xmlReader)
        {
            ReadAttributes(xmlReader); 
            IncrementItemCount(1);
            IDataNode dataNode = null; 
            if (attributes.Ref != Globals.NewObjectId) 
            {
                xmlReader.Skip(); 
                object o = GetExistingObjectOrExtensionData(attributes.Ref);
                dataNode = (o is IDataNode) ? (IDataNode)o : new DataNode(o);
                dataNode.Id = attributes.Ref;
            } 
            else if (attributes.XsiNil)
            { 
                xmlReader.Skip(); 
                dataNode = null;
            } 
            else
            {
                string dataContractName = null;
                string dataContractNamespace = null; 
                if (attributes.XsiTypeName != null)
                { 
                    dataContractName = attributes.XsiTypeName; 
                    dataContractNamespace = attributes.XsiTypeNamespace;
                } 

                if (IsReadingCollectionExtensionData(xmlReader))
                {
                    Read(xmlReader); 
                    dataNode = ReadUnknownCollectionData(xmlReader, dataContractName, dataContractNamespace);
                } 
                else if (attributes.FactoryTypeName != null) 
                {
                    Read(xmlReader); 
                    dataNode = ReadUnknownISerializableData(xmlReader, dataContractName, dataContractNamespace);
                }
                else if (IsReadingClassExtensionData(xmlReader))
                { 
                    Read(xmlReader);
                    dataNode = ReadUnknownClassData(xmlReader, dataContractName, dataContractNamespace); 
                } 
                else
                { 
                    DataContract dataContract = ResolveDataContractFromTypeName();

                    if (dataContract == null)
                        dataNode = ReadExtensionDataValue(xmlReader, dataContractName, dataContractNamespace); 
                    else if (dataContract is XmlDataContract)
                        dataNode = ReadUnknownXmlData(xmlReader, dataContractName, dataContractNamespace); 
                    else 
                    {
                        if (dataContract.IsISerializable) 
                        {
                            Read(xmlReader);
                            dataNode = ReadUnknownISerializableData(xmlReader, dataContractName, dataContractNamespace);
                        } 
                        else if (dataContract is PrimitiveDataContract)
                        { 
                            if (attributes.Id == Globals.NewObjectId) 
                            {
                                Read(xmlReader); 
                                xmlReader.MoveToContent();
                                dataNode = ReadUnknownPrimitiveData(xmlReader, dataContract.UnderlyingType, dataContractName, dataContractNamespace);
                                xmlReader.ReadEndElement();
                            } 
                            else
                            { 
                                dataNode = new DataNode(xmlReader.ReadElementContentAsAnyType(dataContract.UnderlyingType)); 
                                InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
                            } 
                        }
                        else if (dataContract is EnumDataContract)
                        {
                            dataNode = new DataNode(((EnumDataContract)dataContract).ReadEnumValue(xmlReader)); 
                            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
                        } 
                        else if (dataContract is ClassDataContract) 
                        {
                            Read(xmlReader); 
                            dataNode = ReadUnknownClassData(xmlReader, dataContractName, dataContractNamespace);
                        }
                        else if (dataContract is CollectionDataContract)
                        { 
                            Read(xmlReader);
                            dataNode = ReadUnknownCollectionData(xmlReader, dataContractName, dataContractNamespace); 
                        } 
                    }
                } 
            }
            return dataNode;
        }
 
        protected virtual void StartReadExtensionDataValue(XmlReaderDelegator xmlReader)
        { 
        } 

        IDataNode ReadExtensionDataValue(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace) 
        {
            StartReadExtensionDataValue(xmlReader);

            if (attributes.UnrecognizedAttributesFound) 
                return ReadUnknownXmlData(xmlReader, dataContractName, dataContractNamespace);
 
            IDictionary namespacesInScope = xmlReader.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml); 
            Read(xmlReader);
            xmlReader.MoveToContent(); 

            switch (xmlReader.NodeType)
            {
                case XmlNodeType.Text: 
                    return ReadPrimitiveExtensionDataValue(xmlReader, dataContractName, dataContractNamespace);
                case XmlNodeType.Element: 
                    if (xmlReader.NamespaceURI.StartsWith(Globals.DataContractXsdBaseNamespace, StringComparison.Ordinal)) 
                        return ReadUnknownClassData(xmlReader, dataContractName, dataContractNamespace);
                    else 
                        return ReadAndResolveUnknownXmlData(xmlReader, namespacesInScope, dataContractName, dataContractNamespace);

                case XmlNodeType.EndElement:
                    { 
                        // NOTE: cannot distinguish between empty class or IXmlSerializable and typeof(object)
                        IDataNode objNode = ReadUnknownPrimitiveData(xmlReader, Globals.TypeOfObject, dataContractName, dataContractNamespace); 
                        xmlReader.ReadEndElement(); 
                        objNode.IsFinalValue = false;
                        return objNode; 
                    }
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));
            } 
        }
 
        protected virtual IDataNode ReadPrimitiveExtensionDataValue(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace) 
        {
            Type valueType = xmlReader.ValueType; 
            if (valueType == Globals.TypeOfString)
            {
                // NOTE: cannot distinguish other primitives from string (default XmlReader ValueType)
                IDataNode stringNode = new DataNode(xmlReader.ReadContentAsString()); 
                InitializeExtensionDataNode(stringNode, dataContractName, dataContractNamespace);
                stringNode.IsFinalValue = false; 
                xmlReader.ReadEndElement(); 
                return stringNode;
            } 
            else
            {
                IDataNode objNode = ReadUnknownPrimitiveData(xmlReader, valueType, dataContractName, dataContractNamespace);
                xmlReader.ReadEndElement(); 
                return objNode;
            } 
        } 

        protected void InitializeExtensionDataNode(IDataNode dataNode, string dataContractName, string dataContractNamespace) 
        {
            dataNode.DataContractName = dataContractName;
            dataNode.DataContractNamespace = dataContractNamespace;
            dataNode.ClrAssemblyName = attributes.ClrAssembly; 
            dataNode.ClrTypeName = attributes.ClrType;
            AddNewObject(dataNode); 
            dataNode.Id = attributes.Id; 
        }
 
        IDataNode ReadUnknownPrimitiveData(XmlReaderDelegator xmlReader, Type type, string dataContractName, string dataContractNamespace)
        {
            IDataNode dataNode = xmlReader.ReadExtensionData(type);
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace); 
            return dataNode;
        } 
 
        ClassDataNode ReadUnknownClassData(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
        { 
            ClassDataNode dataNode = new ClassDataNode();
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);

            int memberIndex = 0; 
            XmlNodeType nodeType;
            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement) 
            { 
                if (nodeType != XmlNodeType.Element)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader)); 

                if (dataNode.Members == null)
                    dataNode.Members = new List();
                dataNode.Members.Add(ReadExtensionDataMember(xmlReader, memberIndex++)); 
            }
            xmlReader.ReadEndElement(); 
            return dataNode; 
        }
 
        CollectionDataNode ReadUnknownCollectionData(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
        {
            CollectionDataNode dataNode = new CollectionDataNode();
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace); 

            int arraySize = attributes.ArraySZSize; 
            XmlNodeType nodeType; 
            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement)
            { 
                if (nodeType != XmlNodeType.Element)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));

                if (dataNode.ItemName == null) 
                {
                    dataNode.ItemName = xmlReader.LocalName; 
                    dataNode.ItemNamespace = xmlReader.NamespaceURI; 
                }
                if (xmlReader.IsStartElement(dataNode.ItemName, dataNode.ItemNamespace)) 
                {
                    if (dataNode.Items == null)
                        dataNode.Items = new List();
                    dataNode.Items.Add(ReadExtensionDataValue(xmlReader)); 
                }
                else 
                    SkipUnknownElement(xmlReader); 
            }
            xmlReader.ReadEndElement(); 

            if (arraySize != -1)
            {
                dataNode.Size = arraySize; 
                if (dataNode.Items == null)
                { 
                    if (dataNode.Size > 0) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArraySizeAttributeIncorrect, arraySize, 0)));
                } 
                else if (dataNode.Size != dataNode.Items.Count)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArraySizeAttributeIncorrect, arraySize, dataNode.Items.Count)));
            }
            else 
            {
                if (dataNode.Items != null) 
                { 
                    dataNode.Size = dataNode.Items.Count;
                } 
                else
                {
                    dataNode.Size = 0;
                } 
            }
 
            return dataNode; 
        }
 
        ISerializableDataNode ReadUnknownISerializableData(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
        {
            ISerializableDataNode dataNode = new ISerializableDataNode();
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace); 

            dataNode.FactoryTypeName = attributes.FactoryTypeName; 
            dataNode.FactoryTypeNamespace = attributes.FactoryTypeNamespace; 

            XmlNodeType nodeType; 
            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement)
            {
                if (nodeType != XmlNodeType.Element)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader)); 

                if (xmlReader.NamespaceURI.Length != 0) 
                { 
                    SkipUnknownElement(xmlReader);
                    continue; 
                }

                ISerializableDataMember member = new ISerializableDataMember();
                member.Name = xmlReader.LocalName; 
                member.Value = ReadExtensionDataValue(xmlReader);
                if (dataNode.Members == null) 
                    dataNode.Members = new List(); 
                dataNode.Members.Add(member);
            } 
            xmlReader.ReadEndElement();
            return dataNode;
        }
 
        IDataNode ReadUnknownXmlData(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
        { 
            XmlDataNode dataNode = new XmlDataNode(); 
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
            dataNode.OwnerDocument = Document; 

            if (xmlReader.NodeType == XmlNodeType.EndElement)
                return dataNode;
 
            IList xmlAttributes = null;
            IList xmlChildNodes = null; 
 
            XmlNodeType nodeType = xmlReader.MoveToContent();
            if (nodeType != XmlNodeType.Text) 
            {
                while (xmlReader.MoveToNextAttribute())
                {
                    string ns = xmlReader.NamespaceURI; 
                    if (ns != Globals.SerializationNamespace && ns != Globals.SchemaInstanceNamespace)
                    { 
                        if (xmlAttributes == null) 
                            xmlAttributes = new List();
                        xmlAttributes.Add((XmlAttribute)Document.ReadNode(xmlReader.UnderlyingReader)); 
                    }
                }
                Read(xmlReader);
            } 

            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement) 
            { 
                if (xmlReader.EOF)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnexpectedEndOfFile))); 

                if (xmlChildNodes == null)
                    xmlChildNodes = new List();
                xmlChildNodes.Add(Document.ReadNode(xmlReader.UnderlyingReader)); 
            }
            xmlReader.ReadEndElement(); 
 
            dataNode.XmlAttributes = xmlAttributes;
            dataNode.XmlChildNodes = xmlChildNodes; 
            return dataNode;
        }

        // Pattern-recognition logic: the method reads XML elements into DOM. To recognize as an array, it requires that 
        // all items have the same name and namespace. To recognize as an ISerializable type, it requires that all
        // items be unqualified. If the XML only contains elements (no attributes or other nodes) is recognized as a 
        // class/class hierarchy. Otherwise it is deserialized as XML. 
        IDataNode ReadAndResolveUnknownXmlData(XmlReaderDelegator xmlReader, IDictionary namespaces,
            string dataContractName, string dataContractNamespace) 
        {
            bool couldBeISerializableData = true;
            bool couldBeCollectionData = true;
            bool couldBeClassData = true; 
            string elementNs = null, elementName = null;
            IList xmlChildNodes = new List(); 
            IList xmlAttributes = null; 
            if (namespaces != null)
            { 
                xmlAttributes = new List();
                foreach (KeyValuePair prefixNsPair in namespaces)
                {
                    xmlAttributes.Add(AddNamespaceDeclaration(prefixNsPair.Key, prefixNsPair.Value)); 
                }
            } 
 
            XmlNodeType nodeType;
            while ((nodeType = xmlReader.NodeType) != XmlNodeType.EndElement) 
            {
                if (nodeType == XmlNodeType.Element)
                {
                    string ns = xmlReader.NamespaceURI; 
                    string name = xmlReader.LocalName;
                    if (couldBeISerializableData) 
                        couldBeISerializableData = (ns.Length == 0); 
                    if (couldBeCollectionData)
                    { 
                        if (elementName == null)
                        {
                            elementName = name;
                            elementNs = ns; 
                        }
                        else 
                            couldBeCollectionData = (String.CompareOrdinal(elementName, name) == 0) && 
                                (String.CompareOrdinal(elementNs, ns) == 0);
                    } 
                }
                else if (xmlReader.EOF)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnexpectedEndOfFile)));
                else if (IsContentNode(xmlReader.NodeType)) 
                    couldBeClassData = couldBeISerializableData = couldBeCollectionData = false;
 
                if (attributesInXmlData == null) attributesInXmlData = new Attributes(); 
                attributesInXmlData.Read(xmlReader);
 
                XmlNode childNode = Document.ReadNode(xmlReader.UnderlyingReader);
                xmlChildNodes.Add(childNode);

                if (namespaces == null) 
                {
                    if (attributesInXmlData.XsiTypeName != null) 
                        childNode.Attributes.Append(AddNamespaceDeclaration(attributesInXmlData.XsiTypePrefix, attributesInXmlData.XsiTypeNamespace)); 
                    if (attributesInXmlData.FactoryTypeName != null)
                        childNode.Attributes.Append(AddNamespaceDeclaration(attributesInXmlData.FactoryTypePrefix, attributesInXmlData.FactoryTypeNamespace)); 
                }
            }
            xmlReader.ReadEndElement();
 
            if (elementName != null && couldBeCollectionData)
                return ReadUnknownCollectionData(CreateReaderOverChildNodes(xmlAttributes, xmlChildNodes), dataContractName, dataContractNamespace); 
            else if (couldBeISerializableData) 
                return ReadUnknownISerializableData(CreateReaderOverChildNodes(xmlAttributes, xmlChildNodes), dataContractName, dataContractNamespace);
            else if (couldBeClassData) 
                return ReadUnknownClassData(CreateReaderOverChildNodes(xmlAttributes, xmlChildNodes), dataContractName, dataContractNamespace);
            else
            {
                XmlDataNode dataNode = new XmlDataNode(); 
                InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
                dataNode.OwnerDocument = Document; 
                dataNode.XmlChildNodes = xmlChildNodes; 
                dataNode.XmlAttributes = xmlAttributes;
                return dataNode; 
            }
        }

        bool IsContentNode(XmlNodeType nodeType) 
        {
            switch (nodeType) 
            { 
                case XmlNodeType.Whitespace:
                case XmlNodeType.SignificantWhitespace: 
                case XmlNodeType.Comment:
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.DocumentType:
                    return false; 
                default:
                    return true; 
            } 
        }
 
        internal XmlReaderDelegator CreateReaderOverChildNodes(IList xmlAttributes, IList xmlChildNodes)
        {
            XmlNode wrapperElement = CreateWrapperXmlElement(Document, xmlAttributes, xmlChildNodes, null, null, null);
            XmlReaderDelegator nodeReader = CreateReaderDelegatorForReader(new XmlNodeReader(wrapperElement)); 
            nodeReader.MoveToContent();
            Read(nodeReader); 
            return nodeReader; 
        }
 
        internal static XmlNode CreateWrapperXmlElement(XmlDocument document, IList xmlAttributes, IList xmlChildNodes, string prefix, string localName, string ns)
        {
            localName = localName ?? "wrapper";
            ns = ns ?? String.Empty; 
            XmlNode wrapperElement = document.CreateElement(prefix, localName, ns);
            if (xmlAttributes != null) 
            { 
                for (int i = 0; i < xmlAttributes.Count; i++)
                    wrapperElement.Attributes.Append((XmlAttribute)xmlAttributes[i]); 
            }
            if (xmlChildNodes != null)
            {
                for (int i = 0; i < xmlChildNodes.Count; i++) 
                    wrapperElement.AppendChild(xmlChildNodes[i]);
            } 
            return wrapperElement; 
        }
 
        XmlAttribute AddNamespaceDeclaration(string prefix, string ns)
        {
            XmlAttribute attribute = (prefix == null || prefix.Length == 0) ?
                Document.CreateAttribute(null, Globals.XmlnsPrefix, Globals.XmlnsNamespace) : 
                Document.CreateAttribute(Globals.XmlnsPrefix, prefix, Globals.XmlnsNamespace);
            attribute.Value = ns; 
            return attribute; 
        }
 
        public static Exception CreateUnexpectedStateException(XmlNodeType expectedState, XmlReaderDelegator xmlReader)
        {
            return XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(SR.GetString(SR.ExpectingState, expectedState), xmlReader);
        } 

        protected virtual object ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader) 
        { 
            return dataContract.ReadXmlValue(reader, this);
        } 

        protected virtual XmlReaderDelegator CreateReaderDelegatorForReader(XmlReader xmlReader)
        {
            return new XmlReaderDelegator(xmlReader); 
        }
 
        protected virtual bool IsReadingCollectionExtensionData(XmlReaderDelegator xmlReader) 
        {
            return (attributes.ArraySZSize != -1); 
        }

        protected virtual bool IsReadingClassExtensionData(XmlReaderDelegator xmlReader)
        { 
            return false;
        } 
    } 
}

// 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.Collections.Generic;
    using System.Diagnostics; 
    using System.Runtime.Diagnostics;
    using System.ServiceModel.Diagnostics;
    using System.Text;
    using System.Xml; 
    using System.Xml.Serialization;
    using System.Runtime.Serialization.Diagnostics; 
 
#if USE_REFEMIT
    public class XmlObjectSerializerReadContext : XmlObjectSerializerContext 
#else
    internal class XmlObjectSerializerReadContext : XmlObjectSerializerContext
#endif
    { 
        internal Attributes attributes;
        HybridObjectCache deserializedObjects; 
        XmlSerializableReader xmlSerializableReader; 
        XmlDocument xmlDocument;
        Attributes attributesInXmlData; 
        XmlReaderDelegator extensionDataReader;
        object getOnlyCollectionValue;
        bool isGetOnlyCollection;
 
        HybridObjectCache DeserializedObjects
        { 
            get 
            {
                if (deserializedObjects == null) 
                    deserializedObjects = new HybridObjectCache();
                return deserializedObjects;
            }
        } 

        XmlDocument Document 
        { 
            get
            { 
                if (xmlDocument == null)
                    xmlDocument = new XmlDocument();
                return xmlDocument;
            } 
        }
 
        internal override bool IsGetOnlyCollection 
        {
            get { return this.isGetOnlyCollection; } 
            set { this.isGetOnlyCollection = value; }
        }

 
#if USE_REFEMIT
        public object GetCollectionMember() 
#else 
        internal object GetCollectionMember()
#endif 
        {
            return this.getOnlyCollectionValue;
        }
 
#if USE_REFEMIT
        public void StoreCollectionMemberInfo(object collectionMember) 
#else 
        internal void StoreCollectionMemberInfo(object collectionMember)
#endif 
        {
            this.getOnlyCollectionValue = collectionMember;
            this.isGetOnlyCollection = true;
        } 

#if USE_REFEMIT 
        public static void ThrowNullValueReturnedForGetOnlyCollectionException(Type type) 
#else
        internal static void ThrowNullValueReturnedForGetOnlyCollectionException(Type type) 
#endif
        {
            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.NullValueReturnedForGetOnlyCollection, DataContract.GetClrTypeFullName(type))));
        } 

#if USE_REFEMIT 
        public static void ThrowArrayExceededSizeException(int arraySize, Type type) 
#else
        internal static void ThrowArrayExceededSizeException(int arraySize, Type type) 
#endif
        {
            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayExceededSize, arraySize, DataContract.GetClrTypeFullName(type))));
        } 

        internal static XmlObjectSerializerReadContext CreateContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver) 
        { 
            return (serializer.PreserveObjectReferences || serializer.DataContractSurrogate != null)
                ? new XmlObjectSerializerReadContextComplex(serializer, rootTypeDataContract, dataContractResolver) 
                : new XmlObjectSerializerReadContext(serializer, rootTypeDataContract, dataContractResolver);
        }

        internal static XmlObjectSerializerReadContext CreateContext(NetDataContractSerializer serializer) 
        {
            return new XmlObjectSerializerReadContextComplex(serializer); 
        } 

        internal XmlObjectSerializerReadContext(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject) 
            : base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject)
        {
        }
 
        internal XmlObjectSerializerReadContext(DataContractSerializer serializer, DataContract rootTypeDataContract, DataContractResolver dataContractResolver)
            : base(serializer, rootTypeDataContract, dataContractResolver) 
        { 
            this.attributes = new Attributes();
        } 

        protected XmlObjectSerializerReadContext(NetDataContractSerializer serializer)
            : base(serializer)
        { 
            this.attributes = new Attributes();
        } 
 
        public virtual object InternalDeserialize(XmlReaderDelegator xmlReader, int id, RuntimeTypeHandle declaredTypeHandle, string name, string ns)
        { 
            DataContract dataContract = GetDataContract(id, declaredTypeHandle);
            return InternalDeserialize(xmlReader, name, ns, Type.GetTypeFromHandle(declaredTypeHandle),ref dataContract);
        }
 
        internal virtual object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, string name, string ns)
        { 
            DataContract dataContract = GetDataContract(declaredType); 
            return InternalDeserialize(xmlReader, name, ns, declaredType, ref dataContract);
        } 

        internal virtual object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, string name, string ns)
        {
            if (dataContract == null) 
                GetDataContract(declaredType);
            return InternalDeserialize(xmlReader, name, ns, declaredType, ref dataContract); 
        } 

        protected bool TryHandleNullOrRef(XmlReaderDelegator reader, Type declaredType, string name, string ns, ref object retObj) 
        {
            ReadAttributes(reader);

            if (attributes.Ref != Globals.NewObjectId) 
            {
                if (this.isGetOnlyCollection) 
                { 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.IsReferenceGetOnlyCollectionsNotSupported, attributes.Ref, DataContract.GetClrTypeFullName(declaredType))));
                } 
                else
                {
                    retObj = GetExistingObject(attributes.Ref, declaredType, name, ns);
                    reader.Skip(); 
                    return true;
                } 
            } 
            else if (attributes.XsiNil)
            { 
                reader.Skip();
                return true;
            }
            return false; 
        }
 
        protected object InternalDeserialize(XmlReaderDelegator reader, string name, string ns, Type declaredType, ref DataContract dataContract) 
        {
            object retObj = null; 
            if (TryHandleNullOrRef(reader, dataContract.UnderlyingType, name, ns, ref retObj))
                return retObj;

            bool knownTypesAddedInCurrentScope = false; 
            if (dataContract.KnownDataContracts != null)
            { 
                scopedKnownTypes.Push(dataContract.KnownDataContracts); 
                knownTypesAddedInCurrentScope = true;
            } 

            if (attributes.XsiTypeName != null)
            {
                dataContract = ResolveDataContractFromKnownTypes(attributes.XsiTypeName, attributes.XsiTypeNamespace, dataContract, declaredType); 
                if (dataContract == null)
                { 
                    if (DataContractResolver == null) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(reader, SR.GetString(SR.DcTypeNotFoundOnDeserialize, attributes.XsiTypeNamespace, attributes.XsiTypeName, reader.NamespaceURI, reader.LocalName)))); 
                    }
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(reader, SR.GetString(SR.DcTypeNotResolvedOnDeserialize, attributes.XsiTypeNamespace, attributes.XsiTypeName, reader.NamespaceURI, reader.LocalName))));
                }
                knownTypesAddedInCurrentScope = ReplaceScopedKnownTypesTop(dataContract.KnownDataContracts, knownTypesAddedInCurrentScope); 
            }
 
            if (dataContract.IsISerializable && attributes.FactoryTypeName != null) 
            {
                DataContract factoryDataContract = ResolveDataContractFromKnownTypes(attributes.FactoryTypeName, attributes.FactoryTypeNamespace, dataContract, declaredType); 
                if (factoryDataContract != null)
                {
                    if (factoryDataContract.IsISerializable)
                    { 
                        dataContract = factoryDataContract;
                        knownTypesAddedInCurrentScope = ReplaceScopedKnownTypesTop(dataContract.KnownDataContracts, knownTypesAddedInCurrentScope); 
                    } 
                    else
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.FactoryTypeNotISerializable, DataContract.GetClrTypeFullName(factoryDataContract.UnderlyingType), DataContract.GetClrTypeFullName(dataContract.UnderlyingType)))); 
                }
                else
                {
                    if (DiagnosticUtility.ShouldTraceWarning) 
                    {
                        Dictionary values = new Dictionary(2); 
                        values["FactoryType"] = attributes.FactoryTypeNamespace + ":" + attributes.FactoryTypeName; 
                        values["ISerializableType"] = dataContract.StableName.Namespace + ":" + dataContract.StableName.Name;
                        TraceUtility.Trace(TraceEventType.Warning, TraceCode.FactoryTypeNotFound, 
                            SR.GetString(SR.TraceCodeFactoryTypeNotFound), new DictionaryTraceRecord(values));
                    }
                }
            } 

            if (knownTypesAddedInCurrentScope) 
            { 
                object obj = ReadDataContractValue(dataContract, reader);
                scopedKnownTypes.Pop(); 
                return obj;
            }
            else
            { 
                return ReadDataContractValue(dataContract, reader);
            } 
        } 

        bool ReplaceScopedKnownTypesTop(Dictionary knownDataContracts, bool knownTypesAddedInCurrentScope) 
        {
            if (knownTypesAddedInCurrentScope)
            {
                scopedKnownTypes.Pop(); 
                knownTypesAddedInCurrentScope = false;
            } 
            if (knownDataContracts != null) 
            {
                scopedKnownTypes.Push(knownDataContracts); 
                knownTypesAddedInCurrentScope = true;
            }
            return knownTypesAddedInCurrentScope;
        } 

        public static bool MoveToNextElement(XmlReaderDelegator xmlReader) 
        { 
            return (xmlReader.MoveToContent() != XmlNodeType.EndElement);
        } 

        public int GetMemberIndex(XmlReaderDelegator xmlReader, XmlDictionaryString[] memberNames, XmlDictionaryString[] memberNamespaces, int memberIndex, ExtensionDataObject extensionData)
        {
            for (int i = memberIndex + 1; i < memberNames.Length; i++) 
            {
                if (xmlReader.IsStartElement(memberNames[i], memberNamespaces[i])) 
                    return i; 
            }
            HandleMemberNotFound(xmlReader, extensionData, memberIndex); 
            return memberNames.Length;
        }

        public int GetMemberIndexWithRequiredMembers(XmlReaderDelegator xmlReader, XmlDictionaryString[] memberNames, XmlDictionaryString[] memberNamespaces, int memberIndex, int requiredIndex, ExtensionDataObject extensionData) 
        {
            for (int i = memberIndex + 1; i < memberNames.Length; i++) 
            { 
                if (xmlReader.IsStartElement(memberNames[i], memberNamespaces[i]))
                { 
                    if (requiredIndex < i)
                        ThrowRequiredMemberMissingException(xmlReader, memberIndex, requiredIndex, memberNames);
                    return i;
                } 
            }
            HandleMemberNotFound(xmlReader, extensionData, memberIndex); 
            return memberNames.Length; 
        }
 
        public static void ThrowRequiredMemberMissingException(XmlReaderDelegator xmlReader, int memberIndex, int requiredIndex, XmlDictionaryString[] memberNames)
        {
            StringBuilder stringBuilder = new StringBuilder();
            if (requiredIndex == memberNames.Length) 
                requiredIndex--;
            for (int i = memberIndex + 1; i <= requiredIndex; i++) 
            { 
                if (stringBuilder.Length != 0)
                    stringBuilder.Append(" | "); 
                stringBuilder.Append(memberNames[i].Value);
            }
            throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.GetString(SR.UnexpectedElementExpectingElements, xmlReader.NodeType, xmlReader.LocalName, xmlReader.NamespaceURI, stringBuilder.ToString()))));
        } 

        protected void HandleMemberNotFound(XmlReaderDelegator xmlReader, ExtensionDataObject extensionData, int memberIndex) 
        { 
            xmlReader.MoveToContent();
            if (xmlReader.NodeType != XmlNodeType.Element) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));

            if (IgnoreExtensionDataObject || extensionData == null)
                SkipUnknownElement(xmlReader); 
            else
                HandleUnknownElement(xmlReader, extensionData, memberIndex); 
        } 

        internal void HandleUnknownElement(XmlReaderDelegator xmlReader, ExtensionDataObject extensionData, int memberIndex) 
        {
            if (extensionData.Members == null)
                extensionData.Members = new List();
            extensionData.Members.Add(ReadExtensionDataMember(xmlReader, memberIndex)); 
        }
 
        public void SkipUnknownElement(XmlReaderDelegator xmlReader) 
        {
            ReadAttributes(xmlReader); 
            if (DiagnosticUtility.ShouldTraceVerbose)
            {
                TraceUtility.Trace(TraceEventType.Verbose, TraceCode.ElementIgnored,
                    SR.GetString(SR.TraceCodeElementIgnored), new StringTraceRecord("Element", xmlReader.NamespaceURI + ":" + xmlReader.LocalName)); 
            }
            xmlReader.Skip(); 
        } 

        public string ReadIfNullOrRef(XmlReaderDelegator xmlReader, Type memberType, bool isMemberTypeSerializable) 
        {
            if (attributes.Ref != Globals.NewObjectId)
            {
                CheckIfTypeSerializable(memberType, isMemberTypeSerializable); 
                xmlReader.Skip();
                return attributes.Ref; 
            } 
            else if (attributes.XsiNil)
            { 
                CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
                xmlReader.Skip();
                return Globals.NullObjectId;
            } 
            return Globals.NewObjectId;
        } 
 
#if USE_REFEMIT
        public virtual void ReadAttributes(XmlReaderDelegator xmlReader) 
#else
        internal virtual void ReadAttributes(XmlReaderDelegator xmlReader)
#endif
        { 
            if (attributes == null)
                attributes = new Attributes(); 
            attributes.Read(xmlReader); 
        }
 
        public void ResetAttributes()
        {
            if (attributes != null)
                attributes.Reset(); 
        }
 
        public string GetObjectId() 
        {
            return attributes.Id; 
        }

#if USE_REFEMIT
        public virtual int GetArraySize() 
#else
        internal virtual int GetArraySize() 
#endif 
        {
            return -1; 
        }

        public void AddNewObject(object obj)
        { 
            AddNewObjectWithId(attributes.Id, obj);
        } 
 
        public void AddNewObjectWithId(string id, object obj)
        { 
            if (id != Globals.NewObjectId)
                DeserializedObjects.Add(id, obj);
            if (extensionDataReader != null)
                extensionDataReader.UnderlyingExtensionDataReader.SetDeserializedValue(obj); 
        }
 
        public void ReplaceDeserializedObject(string id, object oldObj, object newObj) 
        {
            if (object.ReferenceEquals(oldObj, newObj)) 
                return;

            if (id != Globals.NewObjectId)
            { 
                // In certain cases (IObjectReference, SerializationSurrogate or DataContractSurrogate),
                // an object can be replaced with a different object once it is deserialized. If the 
                // object happens to be referenced from within itself, that reference needs to be updated 
                // with the new instance. BinaryFormatter supports this by fixing up such references later.
                // These XmlObjectSerializer implementations do not currently support fix-ups. Hence we 
                // throw in such cases to allow us add fix-up support in the future if we need to.
                if (DeserializedObjects.IsObjectReferenced(id))
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.FactoryObjectContainsSelfReference, DataContract.GetClrTypeFullName(oldObj.GetType()), DataContract.GetClrTypeFullName(newObj.GetType()), id)));
                DeserializedObjects.Remove(id); 
                DeserializedObjects.Add(id, newObj);
            } 
            if (extensionDataReader != null) 
                extensionDataReader.UnderlyingExtensionDataReader.SetDeserializedValue(newObj);
        } 

        public object GetExistingObject(string id, Type type, string name, string ns)
        {
            object retObj = DeserializedObjects.GetObject(id); 
            if (retObj == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.DeserializedObjectWithIdNotFound, id))); 
            if (retObj is IDataNode) 
            {
                IDataNode dataNode = (IDataNode)retObj; 
                retObj = (dataNode.Value != null && dataNode.IsFinalValue) ? dataNode.Value : DeserializeFromExtensionData(dataNode, type, name, ns);
            }
            return retObj;
        } 

        object GetExistingObjectOrExtensionData(string id) 
        { 
            object retObj = DeserializedObjects.GetObject(id);
            if (retObj == null) 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.DeserializedObjectWithIdNotFound, id)));
            return retObj;
        }
 
        public object GetRealObject(IObjectReference obj, string id)
        { 
            object realObj = SurrogateDataContract.GetRealObject(obj, this.GetStreamingContext()); 
            // If GetRealObject returns null, it indicates that the object could not resolve itself because
            // it is missing information. This may occur in a case where multiple IObjectReference instances 
            // depend on each other. BinaryFormatter supports this by fixing up the references later. These
            // XmlObjectSerializer implementations do not support fix-ups since the format does not contain
            // forward references. However, we throw for this case since it allows us to add fix-up support
            // in the future if we need to. 
            if (realObj == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.GetRealObjectReturnedNull, DataContract.GetClrTypeFullName(obj.GetType())))); 
            ReplaceDeserializedObject(id, obj, realObj); 
            return realObj;
        } 

        object DeserializeFromExtensionData(IDataNode dataNode, Type type, string name, string ns)
        {
            ExtensionDataReader underlyingExtensionDataReader; 
            if (extensionDataReader == null)
            { 
                underlyingExtensionDataReader = new ExtensionDataReader(this); 
                extensionDataReader = CreateReaderDelegatorForReader(underlyingExtensionDataReader);
            } 
            else
                underlyingExtensionDataReader = extensionDataReader.UnderlyingExtensionDataReader;
            underlyingExtensionDataReader.SetDataNode(dataNode, name, ns);
            object retObj = InternalDeserialize(extensionDataReader, type, name, ns); 
            dataNode.Clear();
            underlyingExtensionDataReader.Reset(); 
            return retObj; 
        }
 
        public static void Read(XmlReaderDelegator xmlReader)
        {
            if (!xmlReader.Read())
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnexpectedEndOfFile))); 
        }
 
        internal static void ParseQualifiedName(string qname, XmlReaderDelegator xmlReader, out string name, out string ns, out string prefix) 
        {
            int colon = qname.IndexOf(':'); 
            prefix = "";
            if (colon >= 0)
                prefix = qname.Substring(0, colon);
            name = qname.Substring(colon + 1); 
            ns = xmlReader.LookupNamespace(prefix);
        } 
 
        public static T[] EnsureArraySize(T[] array, int index)
        { 
            if (array.Length <= index)
            {
                if (index == Int32.MaxValue)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        XmlObjectSerializer.CreateSerializationException( 
                        SR.GetString(SR.MaxArrayLengthExceeded, Int32.MaxValue, 
                        DataContract.GetClrTypeFullName(typeof(T)))));
                } 
                int newSize = (index < Int32.MaxValue / 2) ? index * 2 : Int32.MaxValue;
                T[] newArray = new T[newSize];
                Array.Copy(array, 0, newArray, 0, array.Length);
                array = newArray; 
            }
            return array; 
        } 

        public static T[] TrimArraySize(T[] array, int size) 
        {
            if (size != array.Length)
            {
                T[] newArray = new T[size]; 
                Array.Copy(array, 0, newArray, 0, size);
                array = newArray; 
            } 
            return array;
        } 

        public void CheckEndOfArray(XmlReaderDelegator xmlReader, int arraySize, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
        {
            if (xmlReader.NodeType == XmlNodeType.EndElement) 
                return;
            while (xmlReader.IsStartElement()) 
            { 
                if (xmlReader.IsStartElement(itemName, itemNamespace))
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArrayExceededSizeAttribute, arraySize, itemName.Value, itemNamespace.Value))); 
                SkipUnknownElement(xmlReader);
            }
            if (xmlReader.NodeType != XmlNodeType.EndElement)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.EndElement, xmlReader)); 
        }
 
        internal object ReadIXmlSerializable(XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, bool isMemberType) 
        {
            if (xmlSerializableReader == null) 
                xmlSerializableReader = new XmlSerializableReader();
            return ReadIXmlSerializable(xmlSerializableReader, xmlReader, xmlDataContract, isMemberType);
        }
 
        internal static object ReadRootIXmlSerializable(XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, bool isMemberType)
        { 
            return ReadIXmlSerializable(new XmlSerializableReader(), xmlReader, xmlDataContract, isMemberType); 
        }
 
        internal static object ReadIXmlSerializable(XmlSerializableReader xmlSerializableReader, XmlReaderDelegator xmlReader, XmlDataContract xmlDataContract, bool isMemberType)
        {
            object obj = null;
            xmlSerializableReader.BeginRead(xmlReader); 
            if (isMemberType && !xmlDataContract.HasRoot)
            { 
                xmlReader.Read(); 
                xmlReader.MoveToContent();
            } 
            if (xmlDataContract.UnderlyingType == Globals.TypeOfXmlElement)
            {
                if (!xmlReader.IsStartElement())
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader)); 
                XmlDocument xmlDoc = new XmlDocument();
                obj = (XmlElement)xmlDoc.ReadNode(xmlSerializableReader); 
            } 
            else if (xmlDataContract.UnderlyingType == Globals.TypeOfXmlNodeArray)
            { 
                obj = XmlSerializableServices.ReadNodes(xmlSerializableReader);
            }
            else
            { 
                IXmlSerializable xmlSerializable = xmlDataContract.CreateXmlSerializableDelegate();
                xmlSerializable.ReadXml(xmlSerializableReader); 
                obj = xmlSerializable; 
            }
            xmlSerializableReader.EndRead(); 
            return obj;
        }

        public SerializationInfo ReadSerializationInfo(XmlReaderDelegator xmlReader, Type type) 
        {
            SerializationInfo serInfo = new SerializationInfo(type, XmlObjectSerializer.FormatterConverter); 
            XmlNodeType nodeType; 
            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement)
            { 
                if (nodeType != XmlNodeType.Element)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));

                if (xmlReader.NamespaceURI.Length != 0) 
                {
                    SkipUnknownElement(xmlReader); 
                    continue; 
                }
                string name = XmlConvert.DecodeName(xmlReader.LocalName); 

                IncrementItemCount(1);
                ReadAttributes(xmlReader);
                object value; 
                if (attributes.Ref != Globals.NewObjectId)
                { 
                    xmlReader.Skip(); 
                    value = GetExistingObject(attributes.Ref, null, name, String.Empty);
                } 
                else if (attributes.XsiNil)
                {
                    xmlReader.Skip();
                    value = null; 
                }
                else 
                { 
                    value = InternalDeserialize(xmlReader, Globals.TypeOfObject, name, String.Empty);
                } 

                serInfo.AddValue(name, value);
            }
 
            return serInfo;
        } 
 
        protected virtual DataContract ResolveDataContractFromTypeName()
        { 
            return (attributes.XsiTypeName == null) ? null : ResolveDataContractFromKnownTypes(attributes.XsiTypeName, attributes.XsiTypeNamespace, null /*memberTypeContract*/, null);
        }

        ExtensionDataMember ReadExtensionDataMember(XmlReaderDelegator xmlReader, int memberIndex) 
        {
            ExtensionDataMember member = new ExtensionDataMember(); 
            member.Name = xmlReader.LocalName; 
            member.Namespace = xmlReader.NamespaceURI;
            member.MemberIndex = memberIndex; 
            if (xmlReader.UnderlyingExtensionDataReader != null)
            {
                // no need to re-read extension data structure
                member.Value = xmlReader.UnderlyingExtensionDataReader.GetCurrentNode(); 
            }
            else 
                member.Value = ReadExtensionDataValue(xmlReader); 
            return member;
        } 

        public IDataNode ReadExtensionDataValue(XmlReaderDelegator xmlReader)
        {
            ReadAttributes(xmlReader); 
            IncrementItemCount(1);
            IDataNode dataNode = null; 
            if (attributes.Ref != Globals.NewObjectId) 
            {
                xmlReader.Skip(); 
                object o = GetExistingObjectOrExtensionData(attributes.Ref);
                dataNode = (o is IDataNode) ? (IDataNode)o : new DataNode(o);
                dataNode.Id = attributes.Ref;
            } 
            else if (attributes.XsiNil)
            { 
                xmlReader.Skip(); 
                dataNode = null;
            } 
            else
            {
                string dataContractName = null;
                string dataContractNamespace = null; 
                if (attributes.XsiTypeName != null)
                { 
                    dataContractName = attributes.XsiTypeName; 
                    dataContractNamespace = attributes.XsiTypeNamespace;
                } 

                if (IsReadingCollectionExtensionData(xmlReader))
                {
                    Read(xmlReader); 
                    dataNode = ReadUnknownCollectionData(xmlReader, dataContractName, dataContractNamespace);
                } 
                else if (attributes.FactoryTypeName != null) 
                {
                    Read(xmlReader); 
                    dataNode = ReadUnknownISerializableData(xmlReader, dataContractName, dataContractNamespace);
                }
                else if (IsReadingClassExtensionData(xmlReader))
                { 
                    Read(xmlReader);
                    dataNode = ReadUnknownClassData(xmlReader, dataContractName, dataContractNamespace); 
                } 
                else
                { 
                    DataContract dataContract = ResolveDataContractFromTypeName();

                    if (dataContract == null)
                        dataNode = ReadExtensionDataValue(xmlReader, dataContractName, dataContractNamespace); 
                    else if (dataContract is XmlDataContract)
                        dataNode = ReadUnknownXmlData(xmlReader, dataContractName, dataContractNamespace); 
                    else 
                    {
                        if (dataContract.IsISerializable) 
                        {
                            Read(xmlReader);
                            dataNode = ReadUnknownISerializableData(xmlReader, dataContractName, dataContractNamespace);
                        } 
                        else if (dataContract is PrimitiveDataContract)
                        { 
                            if (attributes.Id == Globals.NewObjectId) 
                            {
                                Read(xmlReader); 
                                xmlReader.MoveToContent();
                                dataNode = ReadUnknownPrimitiveData(xmlReader, dataContract.UnderlyingType, dataContractName, dataContractNamespace);
                                xmlReader.ReadEndElement();
                            } 
                            else
                            { 
                                dataNode = new DataNode(xmlReader.ReadElementContentAsAnyType(dataContract.UnderlyingType)); 
                                InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
                            } 
                        }
                        else if (dataContract is EnumDataContract)
                        {
                            dataNode = new DataNode(((EnumDataContract)dataContract).ReadEnumValue(xmlReader)); 
                            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
                        } 
                        else if (dataContract is ClassDataContract) 
                        {
                            Read(xmlReader); 
                            dataNode = ReadUnknownClassData(xmlReader, dataContractName, dataContractNamespace);
                        }
                        else if (dataContract is CollectionDataContract)
                        { 
                            Read(xmlReader);
                            dataNode = ReadUnknownCollectionData(xmlReader, dataContractName, dataContractNamespace); 
                        } 
                    }
                } 
            }
            return dataNode;
        }
 
        protected virtual void StartReadExtensionDataValue(XmlReaderDelegator xmlReader)
        { 
        } 

        IDataNode ReadExtensionDataValue(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace) 
        {
            StartReadExtensionDataValue(xmlReader);

            if (attributes.UnrecognizedAttributesFound) 
                return ReadUnknownXmlData(xmlReader, dataContractName, dataContractNamespace);
 
            IDictionary namespacesInScope = xmlReader.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml); 
            Read(xmlReader);
            xmlReader.MoveToContent(); 

            switch (xmlReader.NodeType)
            {
                case XmlNodeType.Text: 
                    return ReadPrimitiveExtensionDataValue(xmlReader, dataContractName, dataContractNamespace);
                case XmlNodeType.Element: 
                    if (xmlReader.NamespaceURI.StartsWith(Globals.DataContractXsdBaseNamespace, StringComparison.Ordinal)) 
                        return ReadUnknownClassData(xmlReader, dataContractName, dataContractNamespace);
                    else 
                        return ReadAndResolveUnknownXmlData(xmlReader, namespacesInScope, dataContractName, dataContractNamespace);

                case XmlNodeType.EndElement:
                    { 
                        // NOTE: cannot distinguish between empty class or IXmlSerializable and typeof(object)
                        IDataNode objNode = ReadUnknownPrimitiveData(xmlReader, Globals.TypeOfObject, dataContractName, dataContractNamespace); 
                        xmlReader.ReadEndElement(); 
                        objNode.IsFinalValue = false;
                        return objNode; 
                    }
                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));
            } 
        }
 
        protected virtual IDataNode ReadPrimitiveExtensionDataValue(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace) 
        {
            Type valueType = xmlReader.ValueType; 
            if (valueType == Globals.TypeOfString)
            {
                // NOTE: cannot distinguish other primitives from string (default XmlReader ValueType)
                IDataNode stringNode = new DataNode(xmlReader.ReadContentAsString()); 
                InitializeExtensionDataNode(stringNode, dataContractName, dataContractNamespace);
                stringNode.IsFinalValue = false; 
                xmlReader.ReadEndElement(); 
                return stringNode;
            } 
            else
            {
                IDataNode objNode = ReadUnknownPrimitiveData(xmlReader, valueType, dataContractName, dataContractNamespace);
                xmlReader.ReadEndElement(); 
                return objNode;
            } 
        } 

        protected void InitializeExtensionDataNode(IDataNode dataNode, string dataContractName, string dataContractNamespace) 
        {
            dataNode.DataContractName = dataContractName;
            dataNode.DataContractNamespace = dataContractNamespace;
            dataNode.ClrAssemblyName = attributes.ClrAssembly; 
            dataNode.ClrTypeName = attributes.ClrType;
            AddNewObject(dataNode); 
            dataNode.Id = attributes.Id; 
        }
 
        IDataNode ReadUnknownPrimitiveData(XmlReaderDelegator xmlReader, Type type, string dataContractName, string dataContractNamespace)
        {
            IDataNode dataNode = xmlReader.ReadExtensionData(type);
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace); 
            return dataNode;
        } 
 
        ClassDataNode ReadUnknownClassData(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
        { 
            ClassDataNode dataNode = new ClassDataNode();
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);

            int memberIndex = 0; 
            XmlNodeType nodeType;
            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement) 
            { 
                if (nodeType != XmlNodeType.Element)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader)); 

                if (dataNode.Members == null)
                    dataNode.Members = new List();
                dataNode.Members.Add(ReadExtensionDataMember(xmlReader, memberIndex++)); 
            }
            xmlReader.ReadEndElement(); 
            return dataNode; 
        }
 
        CollectionDataNode ReadUnknownCollectionData(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
        {
            CollectionDataNode dataNode = new CollectionDataNode();
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace); 

            int arraySize = attributes.ArraySZSize; 
            XmlNodeType nodeType; 
            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement)
            { 
                if (nodeType != XmlNodeType.Element)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));

                if (dataNode.ItemName == null) 
                {
                    dataNode.ItemName = xmlReader.LocalName; 
                    dataNode.ItemNamespace = xmlReader.NamespaceURI; 
                }
                if (xmlReader.IsStartElement(dataNode.ItemName, dataNode.ItemNamespace)) 
                {
                    if (dataNode.Items == null)
                        dataNode.Items = new List();
                    dataNode.Items.Add(ReadExtensionDataValue(xmlReader)); 
                }
                else 
                    SkipUnknownElement(xmlReader); 
            }
            xmlReader.ReadEndElement(); 

            if (arraySize != -1)
            {
                dataNode.Size = arraySize; 
                if (dataNode.Items == null)
                { 
                    if (dataNode.Size > 0) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArraySizeAttributeIncorrect, arraySize, 0)));
                } 
                else if (dataNode.Size != dataNode.Items.Count)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.ArraySizeAttributeIncorrect, arraySize, dataNode.Items.Count)));
            }
            else 
            {
                if (dataNode.Items != null) 
                { 
                    dataNode.Size = dataNode.Items.Count;
                } 
                else
                {
                    dataNode.Size = 0;
                } 
            }
 
            return dataNode; 
        }
 
        ISerializableDataNode ReadUnknownISerializableData(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
        {
            ISerializableDataNode dataNode = new ISerializableDataNode();
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace); 

            dataNode.FactoryTypeName = attributes.FactoryTypeName; 
            dataNode.FactoryTypeNamespace = attributes.FactoryTypeNamespace; 

            XmlNodeType nodeType; 
            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement)
            {
                if (nodeType != XmlNodeType.Element)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateUnexpectedStateException(XmlNodeType.Element, xmlReader)); 

                if (xmlReader.NamespaceURI.Length != 0) 
                { 
                    SkipUnknownElement(xmlReader);
                    continue; 
                }

                ISerializableDataMember member = new ISerializableDataMember();
                member.Name = xmlReader.LocalName; 
                member.Value = ReadExtensionDataValue(xmlReader);
                if (dataNode.Members == null) 
                    dataNode.Members = new List(); 
                dataNode.Members.Add(member);
            } 
            xmlReader.ReadEndElement();
            return dataNode;
        }
 
        IDataNode ReadUnknownXmlData(XmlReaderDelegator xmlReader, string dataContractName, string dataContractNamespace)
        { 
            XmlDataNode dataNode = new XmlDataNode(); 
            InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
            dataNode.OwnerDocument = Document; 

            if (xmlReader.NodeType == XmlNodeType.EndElement)
                return dataNode;
 
            IList xmlAttributes = null;
            IList xmlChildNodes = null; 
 
            XmlNodeType nodeType = xmlReader.MoveToContent();
            if (nodeType != XmlNodeType.Text) 
            {
                while (xmlReader.MoveToNextAttribute())
                {
                    string ns = xmlReader.NamespaceURI; 
                    if (ns != Globals.SerializationNamespace && ns != Globals.SchemaInstanceNamespace)
                    { 
                        if (xmlAttributes == null) 
                            xmlAttributes = new List();
                        xmlAttributes.Add((XmlAttribute)Document.ReadNode(xmlReader.UnderlyingReader)); 
                    }
                }
                Read(xmlReader);
            } 

            while ((nodeType = xmlReader.MoveToContent()) != XmlNodeType.EndElement) 
            { 
                if (xmlReader.EOF)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnexpectedEndOfFile))); 

                if (xmlChildNodes == null)
                    xmlChildNodes = new List();
                xmlChildNodes.Add(Document.ReadNode(xmlReader.UnderlyingReader)); 
            }
            xmlReader.ReadEndElement(); 
 
            dataNode.XmlAttributes = xmlAttributes;
            dataNode.XmlChildNodes = xmlChildNodes; 
            return dataNode;
        }

        // Pattern-recognition logic: the method reads XML elements into DOM. To recognize as an array, it requires that 
        // all items have the same name and namespace. To recognize as an ISerializable type, it requires that all
        // items be unqualified. If the XML only contains elements (no attributes or other nodes) is recognized as a 
        // class/class hierarchy. Otherwise it is deserialized as XML. 
        IDataNode ReadAndResolveUnknownXmlData(XmlReaderDelegator xmlReader, IDictionary namespaces,
            string dataContractName, string dataContractNamespace) 
        {
            bool couldBeISerializableData = true;
            bool couldBeCollectionData = true;
            bool couldBeClassData = true; 
            string elementNs = null, elementName = null;
            IList xmlChildNodes = new List(); 
            IList xmlAttributes = null; 
            if (namespaces != null)
            { 
                xmlAttributes = new List();
                foreach (KeyValuePair prefixNsPair in namespaces)
                {
                    xmlAttributes.Add(AddNamespaceDeclaration(prefixNsPair.Key, prefixNsPair.Value)); 
                }
            } 
 
            XmlNodeType nodeType;
            while ((nodeType = xmlReader.NodeType) != XmlNodeType.EndElement) 
            {
                if (nodeType == XmlNodeType.Element)
                {
                    string ns = xmlReader.NamespaceURI; 
                    string name = xmlReader.LocalName;
                    if (couldBeISerializableData) 
                        couldBeISerializableData = (ns.Length == 0); 
                    if (couldBeCollectionData)
                    { 
                        if (elementName == null)
                        {
                            elementName = name;
                            elementNs = ns; 
                        }
                        else 
                            couldBeCollectionData = (String.CompareOrdinal(elementName, name) == 0) && 
                                (String.CompareOrdinal(elementNs, ns) == 0);
                    } 
                }
                else if (xmlReader.EOF)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.UnexpectedEndOfFile)));
                else if (IsContentNode(xmlReader.NodeType)) 
                    couldBeClassData = couldBeISerializableData = couldBeCollectionData = false;
 
                if (attributesInXmlData == null) attributesInXmlData = new Attributes(); 
                attributesInXmlData.Read(xmlReader);
 
                XmlNode childNode = Document.ReadNode(xmlReader.UnderlyingReader);
                xmlChildNodes.Add(childNode);

                if (namespaces == null) 
                {
                    if (attributesInXmlData.XsiTypeName != null) 
                        childNode.Attributes.Append(AddNamespaceDeclaration(attributesInXmlData.XsiTypePrefix, attributesInXmlData.XsiTypeNamespace)); 
                    if (attributesInXmlData.FactoryTypeName != null)
                        childNode.Attributes.Append(AddNamespaceDeclaration(attributesInXmlData.FactoryTypePrefix, attributesInXmlData.FactoryTypeNamespace)); 
                }
            }
            xmlReader.ReadEndElement();
 
            if (elementName != null && couldBeCollectionData)
                return ReadUnknownCollectionData(CreateReaderOverChildNodes(xmlAttributes, xmlChildNodes), dataContractName, dataContractNamespace); 
            else if (couldBeISerializableData) 
                return ReadUnknownISerializableData(CreateReaderOverChildNodes(xmlAttributes, xmlChildNodes), dataContractName, dataContractNamespace);
            else if (couldBeClassData) 
                return ReadUnknownClassData(CreateReaderOverChildNodes(xmlAttributes, xmlChildNodes), dataContractName, dataContractNamespace);
            else
            {
                XmlDataNode dataNode = new XmlDataNode(); 
                InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
                dataNode.OwnerDocument = Document; 
                dataNode.XmlChildNodes = xmlChildNodes; 
                dataNode.XmlAttributes = xmlAttributes;
                return dataNode; 
            }
        }

        bool IsContentNode(XmlNodeType nodeType) 
        {
            switch (nodeType) 
            { 
                case XmlNodeType.Whitespace:
                case XmlNodeType.SignificantWhitespace: 
                case XmlNodeType.Comment:
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.DocumentType:
                    return false; 
                default:
                    return true; 
            } 
        }
 
        internal XmlReaderDelegator CreateReaderOverChildNodes(IList xmlAttributes, IList xmlChildNodes)
        {
            XmlNode wrapperElement = CreateWrapperXmlElement(Document, xmlAttributes, xmlChildNodes, null, null, null);
            XmlReaderDelegator nodeReader = CreateReaderDelegatorForReader(new XmlNodeReader(wrapperElement)); 
            nodeReader.MoveToContent();
            Read(nodeReader); 
            return nodeReader; 
        }
 
        internal static XmlNode CreateWrapperXmlElement(XmlDocument document, IList xmlAttributes, IList xmlChildNodes, string prefix, string localName, string ns)
        {
            localName = localName ?? "wrapper";
            ns = ns ?? String.Empty; 
            XmlNode wrapperElement = document.CreateElement(prefix, localName, ns);
            if (xmlAttributes != null) 
            { 
                for (int i = 0; i < xmlAttributes.Count; i++)
                    wrapperElement.Attributes.Append((XmlAttribute)xmlAttributes[i]); 
            }
            if (xmlChildNodes != null)
            {
                for (int i = 0; i < xmlChildNodes.Count; i++) 
                    wrapperElement.AppendChild(xmlChildNodes[i]);
            } 
            return wrapperElement; 
        }
 
        XmlAttribute AddNamespaceDeclaration(string prefix, string ns)
        {
            XmlAttribute attribute = (prefix == null || prefix.Length == 0) ?
                Document.CreateAttribute(null, Globals.XmlnsPrefix, Globals.XmlnsNamespace) : 
                Document.CreateAttribute(Globals.XmlnsPrefix, prefix, Globals.XmlnsNamespace);
            attribute.Value = ns; 
            return attribute; 
        }
 
        public static Exception CreateUnexpectedStateException(XmlNodeType expectedState, XmlReaderDelegator xmlReader)
        {
            return XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(SR.GetString(SR.ExpectingState, expectedState), xmlReader);
        } 

        protected virtual object ReadDataContractValue(DataContract dataContract, XmlReaderDelegator reader) 
        { 
            return dataContract.ReadXmlValue(reader, this);
        } 

        protected virtual XmlReaderDelegator CreateReaderDelegatorForReader(XmlReader xmlReader)
        {
            return new XmlReaderDelegator(xmlReader); 
        }
 
        protected virtual bool IsReadingCollectionExtensionData(XmlReaderDelegator xmlReader) 
        {
            return (attributes.ArraySZSize != -1); 
        }

        protected virtual bool IsReadingClassExtensionData(XmlReaderDelegator xmlReader)
        { 
            return false;
        } 
    } 
}

// 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