| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098 |
- //------------------------------------------------------------
- // 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<string, string> values = new Dictionary<string, string>(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<XmlQualifiedName, DataContract> 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<ExtensionDataMember>();
- 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>(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>(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<object>(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<object>(xmlReader.ReadElementContentAsAnyType(dataContract.UnderlyingType));
- InitializeExtensionDataNode(dataNode, dataContractName, dataContractNamespace);
- }
- }
- else if (dataContract is EnumDataContract)
- {
- dataNode = new DataNode<object>(((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<string, string> 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<object>(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<ExtensionDataMember>();
- 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<IDataNode>();
- 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<ISerializableDataMember>();
- 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<XmlAttribute> xmlAttributes = null;
- IList<XmlNode> 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<XmlAttribute>();
- 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<XmlNode>();
- 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<string, string> namespaces,
- string dataContractName, string dataContractNamespace)
- {
- bool couldBeISerializableData = true;
- bool couldBeCollectionData = true;
- bool couldBeClassData = true;
- string elementNs = null, elementName = null;
- IList<XmlNode> xmlChildNodes = new List<XmlNode>();
- IList<XmlAttribute> xmlAttributes = null;
- if (namespaces != null)
- {
- xmlAttributes = new List<XmlAttribute>();
- foreach (KeyValuePair<string, string> 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<XmlAttribute> xmlAttributes, IList<XmlNode> 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<XmlAttribute> xmlAttributes, IList<XmlNode> 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;
- }
- }
- }
|