| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Runtime;
- using System.Xml;
- namespace System.Runtime.Serialization.Json
- {
- internal partial class JsonFormatReaderGenerator
- {
- partial class CriticalHelper
- {
- internal JsonFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract)
- {
- return (XmlReaderDelegator xr, XmlObjectSerializerReadContextComplexJson ctx, XmlDictionaryString emptyDictionaryString, XmlDictionaryString [] memberNames) => new JsonFormatReaderInterpreter (classContract).ReadFromJson (xr, ctx, emptyDictionaryString, memberNames);
- }
- internal JsonFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
- {
- return (XmlReaderDelegator xr, XmlObjectSerializerReadContextComplexJson ctx, XmlDictionaryString emptyDS, XmlDictionaryString inm, CollectionDataContract cc) => new JsonFormatReaderInterpreter (collectionContract, false).ReadCollectionFromJson (xr, ctx, emptyDS, inm, cc);
- }
-
- internal JsonFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
- {
- return (XmlReaderDelegator xr, XmlObjectSerializerReadContextComplexJson ctx, XmlDictionaryString emptyDS, XmlDictionaryString inm, CollectionDataContract cc) => new JsonFormatReaderInterpreter (collectionContract, true).ReadGetOnlyCollectionFromJson (xr, ctx, emptyDS, inm, cc);
- }
- }
- }
- class JsonFormatReaderInterpreter
- {
- public JsonFormatReaderInterpreter (ClassDataContract classContract)
- {
- this.classContract = classContract;
- }
- public JsonFormatReaderInterpreter (CollectionDataContract collectionContract, bool isGetOnly)
- {
- this.collectionContract = collectionContract;
- this.is_get_only_collection = isGetOnly;
- }
- bool is_get_only_collection;
- ClassDataContract classContract;
- CollectionDataContract collectionContract;
- object objectLocal;
- Type objectType;
- XmlReaderDelegator xmlReader;
- XmlObjectSerializerReadContextComplexJson context;
- XmlDictionaryString [] memberNames = null;
- XmlDictionaryString emptyDictionaryString = null;
- XmlDictionaryString itemName = null;
- XmlDictionaryString itemNamespace = null;
- public object ReadFromJson (XmlReaderDelegator xmlReader, XmlObjectSerializerReadContextComplexJson context, XmlDictionaryString emptyDictionaryString, XmlDictionaryString[] memberNames)
- {
- // InitArgs()
- this.xmlReader = xmlReader;
- this.context = context;
- this.emptyDictionaryString = emptyDictionaryString;
- this.memberNames = memberNames;
-
- //DemandSerializationFormatterPermission(classContract);
- //DemandMemberAccessPermission(memberAccessFlag);
- CreateObject (classContract);
-
- context.AddNewObject (objectLocal);
- InvokeOnDeserializing (classContract);
-
- string objectId = null;
-
- if (classContract.IsISerializable)
- ReadISerializable (classContract);
- else
- ReadClass (classContract);
- if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom (classContract.UnderlyingType))
- ((IDeserializationCallback) objectLocal).OnDeserialization (null);
- InvokeOnDeserialized(classContract);
- if (!InvokeFactoryMethod (classContract)) {
- // Do a conversion back from DateTimeOffsetAdapter to DateTimeOffset after deserialization.
- // DateTimeOffsetAdapter is used here for deserialization purposes to bypass the ISerializable implementation
- // on DateTimeOffset; which does not work in partial trust.
- if (classContract.UnderlyingType == Globals.TypeOfDateTimeOffsetAdapter)
- objectLocal = DateTimeOffsetAdapter.GetDateTimeOffset ((DateTimeOffsetAdapter) objectLocal);
- // else - do we have to call CodeInterpreter.ConvertValue()? I guess not...
- }
- return objectLocal;
- }
-
- public object ReadCollectionFromJson (XmlReaderDelegator xmlReader, XmlObjectSerializerReadContextComplexJson context, XmlDictionaryString emptyDictionaryString, XmlDictionaryString itemName, CollectionDataContract collectionContract)
- {
- #region GenerateCollectionReaderHelper
- // InitArgs()
- this.xmlReader = xmlReader;
- this.context = context;
- this.emptyDictionaryString = emptyDictionaryString;
- this.itemName = itemName;
- this.collectionContract = collectionContract;
- #endregion
- ReadCollection (collectionContract);
- return objectLocal;
- }
-
- public void ReadGetOnlyCollectionFromJson (XmlReaderDelegator xmlReader, XmlObjectSerializerReadContextComplexJson context, XmlDictionaryString emptyDictionaryString, XmlDictionaryString itemName, CollectionDataContract collectionContract)
- {
- #region GenerateCollectionReaderHelper
- // InitArgs()
- this.xmlReader = xmlReader;
- this.context = context;
- this.emptyDictionaryString = emptyDictionaryString;
- this.itemName = itemName;
- this.collectionContract = collectionContract;
- #endregion
- ReadGetOnlyCollection (collectionContract);
- }
- void CreateObject (ClassDataContract classContract)
- {
- Type type = objectType = classContract.UnderlyingType;
- if (type.IsValueType && !classContract.IsNonAttributedType)
- type = Globals.TypeOfValueType;
- if (classContract.UnderlyingType == Globals.TypeOfDBNull)
- objectLocal = DBNull.Value;
- else if (classContract.IsNonAttributedType) {
- if (type.IsValueType)
- objectLocal = FormatterServices.GetUninitializedObject (type);
- else
- objectLocal = classContract.GetNonAttributedTypeConstructor ().Invoke (new object [0]);
- }
- else
- objectLocal = CodeInterpreter.ConvertValue (XmlFormatReaderGenerator.UnsafeGetUninitializedObject (DataContract.GetIdForInitialization (classContract)), Globals.TypeOfObject, type);
- }
- void InvokeOnDeserializing (ClassDataContract classContract)
- {
- if (classContract.BaseContract != null)
- InvokeOnDeserializing (classContract.BaseContract);
- if (classContract.OnDeserializing != null)
- classContract.OnDeserializing.Invoke (objectLocal, new object [] {context.GetStreamingContext ()});
- }
- void InvokeOnDeserialized (ClassDataContract classContract)
- {
- if (classContract.BaseContract != null)
- InvokeOnDeserialized (classContract.BaseContract);
- if (classContract.OnDeserialized != null)
- classContract.OnDeserialized.Invoke (objectLocal, new object [] {context.GetStreamingContext ()});
- }
- bool HasFactoryMethod (ClassDataContract classContract)
- {
- return Globals.TypeOfIObjectReference.IsAssignableFrom (classContract.UnderlyingType);
- }
- bool InvokeFactoryMethod (ClassDataContract classContract)
- {
- if (HasFactoryMethod (classContract)) {
- objectLocal = CodeInterpreter.ConvertValue (context.GetRealObject ((IObjectReference) objectLocal, Globals.NewObjectId), Globals.TypeOfObject, classContract.UnderlyingType);
- return true;
- }
- return false;
- }
- void ReadISerializable (ClassDataContract classContract)
- {
- ConstructorInfo ctor = classContract.UnderlyingType.GetConstructor (Globals.ScanAllMembers, null, JsonFormatGeneratorStatics.SerInfoCtorArgs, null);
- if (ctor == null)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError (XmlObjectSerializer.CreateSerializationException (SR.GetString (SR.SerializationInfo_ConstructorNotFound, DataContract.GetClrTypeFullName (classContract.UnderlyingType))));
- context.ReadSerializationInfo (xmlReader, classContract.UnderlyingType);
- ctor.Invoke (objectLocal, new object [] {context.GetStreamingContext ()});
- }
- void ReadClass (ClassDataContract classContract)
- {
- if (classContract.HasExtensionData) {
- ExtensionDataObject extensionData = new ExtensionDataObject ();
- ReadMembers (classContract, extensionData);
- ClassDataContract currentContract = classContract;
- while (currentContract != null) {
- MethodInfo extensionDataSetMethod = currentContract.ExtensionDataSetMethod;
- if (extensionDataSetMethod != null)
- extensionDataSetMethod.Invoke (objectLocal, new object [] {extensionData});
- currentContract = currentContract.BaseContract;
- }
- }
- else
- ReadMembers (classContract, null);
- }
- void ReadMembers (ClassDataContract classContract, ExtensionDataObject extensionData)
- {
- int memberCount = classContract.MemberNames.Length;
- context.IncrementItemCount (memberCount);
- int memberIndex = -1;
-
- // JSON intrinsic part.
- BitFlagsGenerator expectedElements = new BitFlagsGenerator (memberCount);
- byte [] requiredElements = new byte [expectedElements.GetLocalCount ()];
- SetRequiredElements (classContract, requiredElements);
- SetExpectedElements (expectedElements, 0 /*startIndex*/);
- while (XmlObjectSerializerReadContext.MoveToNextElement (xmlReader)) {
- int idx; // used as in "switch (idx)" in the original source.
- idx = context.GetJsonMemberIndex (xmlReader, memberNames, memberIndex, extensionData);
- if (memberCount > 0)
- ReadMembers (idx, classContract, expectedElements, ref memberIndex);
- }
- if (!CheckRequiredElements (expectedElements, requiredElements))
- XmlObjectSerializerReadContextComplexJson.ThrowMissingRequiredMembers (objectLocal, memberNames, expectedElements.LoadArray (), requiredElements);
- }
- int ReadMembers (int index, ClassDataContract classContract, BitFlagsGenerator expectedElements, ref int memberIndex)
- {
- int memberCount = (classContract.BaseContract == null) ? 0 : ReadMembers (index, classContract.BaseContract, expectedElements,
- ref memberIndex);
-
- if (memberCount <= index && index < memberCount + classContract.Members.Count) {
- DataMember dataMember = classContract.Members [index - memberCount];
- Type memberType = dataMember.MemberType;
-
- memberIndex = memberCount;
- if (!expectedElements.Load (memberCount))
- XmlObjectSerializerReadContextComplexJson.ThrowDuplicateMemberException (objectLocal, memberNames, memberIndex);
- if (dataMember.IsGetOnlyCollection) {
- var value = CodeInterpreter.GetMember (dataMember.MemberInfo, objectLocal);
- context.StoreCollectionMemberInfo (value);
- ReadValue (memberType, dataMember.Name);
- } else {
- var value = ReadValue (memberType, dataMember.Name);
- CodeInterpreter.SetMember (dataMember.MemberInfo, objectLocal, value);
- }
- memberIndex = index;
- ResetExpectedElements(expectedElements, index);
- }
- return memberCount + classContract.Members.Count;
- }
- bool CheckRequiredElements (BitFlagsGenerator expectedElements, byte [] requiredElements)
- {
- for (int i = 0; i < requiredElements.Length; i++)
- if ((expectedElements.GetLocal(i) & requiredElements[i]) != 0)
- return false;
- return true;
- }
- int SetRequiredElements (ClassDataContract contract, byte [] requiredElements)
- {
- int memberCount = (contract.BaseContract == null) ? 0 :
- SetRequiredElements (contract.BaseContract, requiredElements);
- List<DataMember> members = contract.Members;
- for (int i = 0; i < members.Count; i++, memberCount++) {
- if (members[i].IsRequired)
- BitFlagsGenerator.SetBit (requiredElements, memberCount);
- }
- return memberCount;
- }
- void SetExpectedElements (BitFlagsGenerator expectedElements, int startIndex)
- {
- int memberCount = expectedElements.GetBitCount ();
- for (int i = startIndex; i < memberCount; i++)
- expectedElements.Store (i, true);
- }
- void ResetExpectedElements (BitFlagsGenerator expectedElements, int index)
- {
- expectedElements.Store (index, false);
- }
- object ReadValue (Type type, string name)
- {
- var valueType = type;
- object value = null;
- bool shouldAssignNullableValue = false;
- int nullables = 0;
- while (type.IsGenericType && type.GetGenericTypeDefinition () == Globals.TypeOfNullable) {
- nullables++;
- type = type.GetGenericArguments () [0];
- }
-
- PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract (type);
- if ((primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject) || nullables != 0 || type.IsValueType) {
- context.ReadAttributes (xmlReader);
- string objectId = context.ReadIfNullOrRef (xmlReader, type, DataContract.IsTypeSerializable (type));
- // Deserialize null
- if (objectId == Globals.NullObjectId) {
-
- if (nullables != 0)
- value = Activator.CreateInstance (valueType);
- else if (type.IsValueType)
- throw new SerializationException (SR.GetString (SR.ValueTypeCannotBeNull, DataContract.GetClrTypeFullName (type)));
- else
- value = null;
- } else if (objectId == string.Empty) {
- // Deserialize value
- // Compare against Globals.NewObjectId, which is set to string.Empty
-
- objectId = context.GetObjectId ();
-
- if (type.IsValueType) {
- if (!string.IsNullOrEmpty (objectId))
- throw new SerializationException (SR.GetString (SR.ValueTypeCannotHaveId, DataContract.GetClrTypeFullName(type)));
- }
- object innerValueRead = null;
- if (nullables != 0)
- shouldAssignNullableValue = true;
- if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject) {
- value = primitiveContract.XmlFormatReaderMethod.Invoke (xmlReader, new object [0]);
- if (!type.IsValueType)
- context.AddNewObject (value);
- }
- else
- value = InternalDeserialize (type, name);
- } else {
- // Deserialize ref
- if (type.IsValueType)
- throw new SerializationException (SR.GetString (SR.ValueTypeCannotHaveRef, DataContract.GetClrTypeFullName (type)));
- else
- value = CodeInterpreter.ConvertValue (context.GetExistingObject (objectId, type, name, string.Empty), Globals.TypeOfObject, type);
- }
- if (shouldAssignNullableValue) {
- if (objectId != Globals.NullObjectId)
- value = WrapNullableObject (type, value, valueType, nullables);
- }
- }
- else
- value = InternalDeserialize (type, name);
- return value;
- }
- object InternalDeserialize (Type type, string name)
- {
- Type declaredType = type.IsPointer ? Globals.TypeOfReflectionPointer : type;
- var obj = context.InternalDeserialize (xmlReader, DataContract.GetId (declaredType.TypeHandle), declaredType.TypeHandle, name, string.Empty);
- if (type.IsPointer)
- // wow, there is no way to convert void* to object in strongly typed way...
- return JsonFormatGeneratorStatics.UnboxPointer.Invoke (null, new object [] {obj});
- else
- return CodeInterpreter.ConvertValue (obj, Globals.TypeOfObject, type);
- }
- object WrapNullableObject (Type innerType, object innerValue, Type outerType, int nullables)
- {
- var outerValue = innerValue;
- for (int i = 1; i < nullables; i++) {
- Type type = Globals.TypeOfNullable.MakeGenericType (innerType);
- outerValue = Activator.CreateInstance (type, new object[] { outerValue });
- innerType = type;
- }
- return Activator.CreateInstance (outerType, new object[] { outerValue });
- }
- void ReadCollection (CollectionDataContract collectionContract)
- {
- Type type = collectionContract.UnderlyingType;
- Type itemType = collectionContract.ItemType;
- bool isArray = (collectionContract.Kind == CollectionKind.Array);
- ConstructorInfo constructor = collectionContract.Constructor;
- if (type.IsInterface) {
- switch (collectionContract.Kind) {
- case CollectionKind.GenericDictionary:
- type = Globals.TypeOfDictionaryGeneric.MakeGenericType (itemType.GetGenericArguments ());
- constructor = type.GetConstructor (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Globals.EmptyTypeArray, null);
- break;
- case CollectionKind.Dictionary:
- type = Globals.TypeOfHashtable;
- constructor = type.GetConstructor (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Globals.EmptyTypeArray, null);
- break;
- case CollectionKind.Collection:
- case CollectionKind.GenericCollection:
- case CollectionKind.Enumerable:
- case CollectionKind.GenericEnumerable:
- case CollectionKind.List:
- case CollectionKind.GenericList:
- type = itemType.MakeArrayType ();
- isArray = true;
- break;
- }
- }
- if (!isArray) {
- if (type.IsValueType)
- // FIXME: this is not what the original code does.
- objectLocal = FormatterServices.GetUninitializedObject (type);
- else {
- objectLocal = constructor.Invoke (new object [0]);
- context.AddNewObject (objectLocal);
- }
- }
- bool canReadSimpleDictionary = collectionContract.Kind == CollectionKind.Dictionary ||
- collectionContract.Kind == CollectionKind.GenericDictionary;
- if (canReadSimpleDictionary & context.UseSimpleDictionaryFormat)
- ReadSimpleDictionary (collectionContract, itemType);
- else {
- string objectId = context.GetObjectId ();
- bool canReadPrimitiveArray = false, readResult = false;
- if (isArray && TryReadPrimitiveArray (itemType, out readResult))
- canReadPrimitiveArray = true;
- if (!readResult) {
- object growingCollection = null;
- if (isArray)
- growingCollection = Array.CreateInstance (itemType, 32);
- int i = 0;
- // FIXME: I cannot find i++ part, but without that it won't work as expected.
- for (; i < int.MaxValue; i++) {
- if (IsStartElement (this.itemName, this.emptyDictionaryString)) {
- context.IncrementItemCount (1);
- object value = ReadCollectionItem (collectionContract, itemType);
- if (isArray) {
- MethodInfo ensureArraySizeMethod = XmlFormatGeneratorStatics.EnsureArraySizeMethod.MakeGenericMethod (itemType);
- growingCollection = ensureArraySizeMethod.Invoke (null, new object [] {growingCollection, i});
- ((Array) growingCollection).SetValue (value, i);
- } else {
- StoreCollectionValue (objectLocal, itemType, value, collectionContract);
- }
- }
- else if (IsEndElement ())
- break;
- else
- HandleUnexpectedItemInCollection (ref i);
- }
- if (isArray) {
- MethodInfo trimArraySizeMethod = XmlFormatGeneratorStatics.TrimArraySizeMethod.MakeGenericMethod (itemType);
- objectLocal = trimArraySizeMethod.Invoke (null, new object [] {growingCollection, i});
- context.AddNewObjectWithId (objectId, objectLocal);
- }
- }
- if (canReadPrimitiveArray)
- context.AddNewObjectWithId (objectId, objectLocal);
- }
- }
- void ReadSimpleDictionary (CollectionDataContract collectionContract, Type keyValueType)
- {
- Type[] keyValueTypes = keyValueType.GetGenericArguments ();
- Type keyType = keyValueTypes [0];
- Type valueType = keyValueTypes [1];
- int keyTypeNullableDepth = 0;
- Type keyTypeOriginal = keyType;
- while (keyType.IsGenericType && keyType.GetGenericTypeDefinition () == Globals.TypeOfNullable) {
- keyTypeNullableDepth++;
- keyType = keyType.GetGenericArguments () [0];
- }
- ClassDataContract keyValueDataContract = (ClassDataContract)collectionContract.ItemContract;
- DataContract keyDataContract = keyValueDataContract.Members [0].MemberTypeContract;
- KeyParseMode keyParseMode = KeyParseMode.Fail;
- if (keyType == Globals.TypeOfString || keyType == Globals.TypeOfObject) {
- keyParseMode = KeyParseMode.AsString;
- } else if (keyType.IsEnum) {
- keyParseMode = KeyParseMode.UsingParseEnum;
- } else if (keyDataContract.ParseMethod != null) {
- keyParseMode = KeyParseMode.UsingCustomParse;
- }
- if (keyParseMode == KeyParseMode.Fail) {
- ThrowSerializationException (
- SR.GetString (
- SR.KeyTypeCannotBeParsedInSimpleDictionary,
- DataContract.GetClrTypeFullName (collectionContract.UnderlyingType),
- DataContract.GetClrTypeFullName (keyType)));
- } else {
- XmlNodeType nodeType;
- while ((nodeType = xmlReader.MoveToContent ()) != XmlNodeType.EndElement) {
- if (nodeType != XmlNodeType.Element)
- ThrowUnexpectedStateException (XmlNodeType.Element);
- context.IncrementItemCount (1);
- var jsonMemberName = XmlObjectSerializerReadContextComplexJson.GetJsonMemberName (xmlReader);
- object key = null;
- if (keyParseMode == KeyParseMode.UsingParseEnum)
- key = Enum.Parse (keyType, jsonMemberName);
- else if (keyParseMode == KeyParseMode.UsingCustomParse)
- key = keyDataContract.ParseMethod.Invoke (null, new object [] {jsonMemberName});
- if (keyTypeNullableDepth > 0) {
- var keyOriginal = WrapNullableObject (keyType, key, valueType, keyTypeNullableDepth);
- key = keyOriginal;
- }
- var value = ReadValue (valueType, String.Empty);
- collectionContract.AddMethod.Invoke (objectLocal, new object[] {key, value});
- }
- }
- }
- // CONTINUE FROM HERE
- void ReadGetOnlyCollection (CollectionDataContract collectionContract)
- {
- Type type = collectionContract.UnderlyingType;
- Type itemType = collectionContract.ItemType;
- bool isArray = (collectionContract.Kind == CollectionKind.Array);
- int size = 0;
- objectLocal = context.GetCollectionMember ();
-
- bool canReadSimpleDictionary =
- collectionContract.Kind == CollectionKind.Dictionary ||
- collectionContract.Kind == CollectionKind.GenericDictionary;
- bool readSimple = canReadSimpleDictionary && context.UseSimpleDictionaryFormat;
- if (readSimple) {
- if (objectLocal == null)
- XmlObjectSerializerReadContext.ThrowNullValueReturnedForGetOnlyCollectionException (type);
- else {
- ReadSimpleDictionary(collectionContract, itemType);
- context.CheckEndOfArray (xmlReader, size, this.itemName, emptyDictionaryString);
- }
- } else {
- //check that items are actually going to be deserialized into the collection
- if (IsStartElement (this.itemName, this.emptyDictionaryString)) {
- if (objectLocal == null)
- XmlObjectSerializerReadContext.ThrowNullValueReturnedForGetOnlyCollectionException (type);
- else {
- size = 0;
- if (isArray)
- size = ((Array) objectLocal).Length;
- for (int i = 0; i < int.MaxValue;) {
- if (IsStartElement (this.itemName, this.emptyDictionaryString)) {
- context.IncrementItemCount (1);
- var value = ReadCollectionItem (collectionContract, itemType);
- if (isArray) {
- if (size == i)
- XmlObjectSerializerReadContext.ThrowArrayExceededSizeException (size, type);
- else
- ((Array) objectLocal).SetValue (value, i);
- } else {
- StoreCollectionValue (objectLocal, itemType, value, collectionContract);
- }
- }
- else if (IsEndElement())
- break;
- else
- HandleUnexpectedItemInCollection (ref i);
- }
- context.CheckEndOfArray (xmlReader, size, this.itemName, this.emptyDictionaryString);
- }
- }
- }
- }
- bool TryReadPrimitiveArray (Type itemType, out bool readResult)
- {
- readResult = false;
- PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract (itemType);
- if (primitiveContract == null)
- return false;
- string readArrayMethod = null;
- switch (Type.GetTypeCode (itemType))
- {
- case TypeCode.Boolean:
- readArrayMethod = "TryReadBooleanArray";
- break;
- case TypeCode.Decimal:
- readArrayMethod = "TryReadDecimalArray";
- break;
- case TypeCode.Int32:
- readArrayMethod = "TryReadInt32Array";
- break;
- case TypeCode.Int64:
- readArrayMethod = "TryReadInt64Array";
- break;
- case TypeCode.Single:
- readArrayMethod = "TryReadSingleArray";
- break;
- case TypeCode.Double:
- readArrayMethod = "TryReadDoubleArray";
- break;
- case TypeCode.DateTime:
- readArrayMethod = "TryReadJsonDateTimeArray";
- break;
- default:
- break;
- }
- if (readArrayMethod != null) {
- var mi = typeof (JsonReaderDelegator).GetMethod (readArrayMethod, Globals.ScanAllMembers);
- var args = new object [] {context, itemName, emptyDictionaryString, -1, objectLocal};
- readResult = (bool) mi.Invoke ((JsonReaderDelegator) xmlReader, args);
- objectLocal = args.Last ();
- return true;
- }
- return false;
- }
- object ReadCollectionItem (CollectionDataContract collectionContract, Type itemType)
- {
- if (collectionContract.Kind == CollectionKind.Dictionary || collectionContract.Kind == CollectionKind.GenericDictionary) {
- context.ResetAttributes ();
- var v = DataContractJsonSerializer.ReadJsonValue (XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract (collectionContract.ItemContract), xmlReader, context);
- return CodeInterpreter.ConvertValue (v, Globals.TypeOfObject, itemType);
- }
- else
- return ReadValue (itemType, JsonGlobals.itemString);
- }
- void StoreCollectionValue (object collection, Type valueType, object value, CollectionDataContract collectionContract)
- {
- if (collectionContract.Kind == CollectionKind.GenericDictionary || collectionContract.Kind == CollectionKind.Dictionary) {
- ClassDataContract keyValuePairContract = DataContract.GetDataContract (valueType) as ClassDataContract;
- if (keyValuePairContract == null)
- Fx.Assert ("Failed to create contract for KeyValuePair type");
- DataMember keyMember = keyValuePairContract.Members [0];
- DataMember valueMember = keyValuePairContract.Members [1];
- object pkey = CodeInterpreter.GetMember (keyMember.MemberInfo, value);
- object pvalue = CodeInterpreter.GetMember (valueMember.MemberInfo, value);
-
- collectionContract.AddMethod.Invoke (collection, new object [] {pkey, pvalue});
- }
- else
- collectionContract.AddMethod.Invoke (collection, new object [] {value});
- }
- void HandleUnexpectedItemInCollection (ref int iterator)
- {
- if (IsStartElement ()) {
- context.SkipUnknownElement (xmlReader);
- iterator--;
- }
- else
- throw XmlObjectSerializerReadContext.CreateUnexpectedStateException (XmlNodeType.Element, xmlReader);
- }
- bool IsStartElement(XmlDictionaryString name, XmlDictionaryString ns)
- {
- return xmlReader.IsStartElement (name, ns);
- }
- bool IsStartElement()
- {
- return xmlReader.IsStartElement ();
- }
- bool IsEndElement ()
- {
- return xmlReader.NodeType == XmlNodeType.EndElement;
- }
- void ThrowUnexpectedStateException (XmlNodeType expectedState)
- {
- throw XmlObjectSerializerReadContext.CreateUnexpectedStateException (expectedState, xmlReader);
- }
- void ThrowSerializationException (string msg, params object [] values)
- {
- if (values != null && values.Length > 0)
- msg = string.Format (msg, values);
- throw new SerializationException (msg);
- }
- enum KeyParseMode
- {
- Fail,
- AsString,
- UsingParseEnum,
- UsingCustomParse
- }
- }
- }
|