public static List<object> ConvertGenericDictionaryToArray(DataContractJsonSerializer serializer, IEnumerable value, CollectionDataContract dataContract, XmlObjectSerializerWriteContextComplexJson context, bool writeServerType)
        {
            List<object> keyValuePair = new List<object>();
            Dictionary<string, object> currentEntry;
            Type[] declaredTypes = dataContract.ItemType.GetGenericArguments();
            MethodInfo getEnumeratorMethod = dataContract.GetEnumeratorMethod;

            IDictionaryEnumerator enumerator = (IDictionaryEnumerator)((getEnumeratorMethod == null) ? value.GetEnumerator() : (IDictionaryEnumerator)getEnumeratorMethod.Invoke(value, Array.Empty<Type>()));
            while (enumerator.MoveNext())
            {
                DictionaryEntry current = enumerator.Entry;
                DataContract currentDataContract = DataContract.GetDataContract(enumerator.Current.GetType());
                currentEntry = new Dictionary<string, object>();
                if (writeServerType)
                {
                    AddTypeInformation(currentEntry, currentDataContract);
                }
                context.PushKnownTypes(dataContract);
                AddDictionaryEntryData(serializer, currentEntry, writeServerType ? JsonGlobals.KeyString.ToLowerInvariant() : JsonGlobals.KeyString, declaredTypes[0], current.Key, context);
                AddDictionaryEntryData(serializer, currentEntry, writeServerType ? JsonGlobals.ValueString.ToLowerInvariant() : JsonGlobals.ValueString, declaredTypes[1], current.Value, context);
                keyValuePair.Add(currentEntry);
                context.PopKnownTypes(dataContract);
            }
            return keyValuePair;
        }
        public static IEnumerable ConvertGenericListToArray(DataContractJsonSerializer serializer, IEnumerable value, CollectionDataContract dataContract, XmlObjectSerializerWriteContextComplexJson context, bool writeServerType)
        {
            Type listArgumentType = dataContract.ItemType;
            if (listArgumentType.GetTypeInfo().IsGenericType)
            {
                listArgumentType = listArgumentType.GetGenericArguments()[0];
            }
            List<object> serializedList = new List<object>();
            MethodInfo getEnumeratorMethod = dataContract.GetEnumeratorMethod;

            IEnumerator enumerator = (getEnumeratorMethod == null) ? value.GetEnumerator() : (IEnumerator)getEnumeratorMethod.Invoke(value, Array.Empty<Type>());
            while (enumerator.MoveNext())
            {
                if (enumerator.Current == null || enumerator.Current.GetType().GetTypeInfo().IsPrimitive)
                {
                    serializedList.Add(enumerator.Current);
                }
                else
                {
                    Type currentItemType = enumerator.Current.GetType();
                    DataContract currentItemDataContract = DataContract.GetDataContract(currentItemType);
                    bool emitTypeInformation = EmitTypeInformation(dataContract.ItemContract, currentItemType);
                    if (writeServerType || emitTypeInformation)
                    {
                        context.CheckIfTypeNeedsVerifcation(dataContract.ItemContract, currentItemDataContract);
                    }
                    context.PushKnownTypes(dataContract);
                    serializedList.Add(serializer.ConvertDataContractToObject(enumerator.Current, currentItemDataContract, context, (writeServerType || emitTypeInformation), dataContract.ItemType.TypeHandle));
                    context.PopKnownTypes(dataContract);
                }
            }
            return serializedList;
        }
		public void WriteCollectionToJson (XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContextComplexJson context, CollectionDataContract dataContract)
		{
			this.writer = xmlWriter;
			this.obj = obj;
			this.context = context;
			this.dataContract = dataContract;

			InitArgs (collectionContract.UnderlyingType);			

			// DemandMemberAccessPermission(memberAccessFlag);
			if (collectionContract.IsReadOnlyContract)
			{
				DataContract.ThrowInvalidDataContractException (collectionContract.SerializationExceptionMessage, null);
			}

			WriteCollection (collectionContract);
		}
        public XmlFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
        {
            try
            {
                if (TD.DCGenReaderStartIsEnabled())
                {
                    TD.DCGenReaderStart("GetOnlyCollection", collectionContract.UnderlyingType.FullName);
                }

                return helper.GenerateGetOnlyCollectionReader(collectionContract);
            }
            finally
            {
                if (TD.DCGenReaderStopIsEnabled())
                {
                    TD.DCGenReaderStop();
                }
            }
        }
        internal JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
        {
            try
            {
                if (TD.DCJsonGenWriterStartIsEnabled())
                {
                    TD.DCJsonGenWriterStart("Collection", collectionContract.UnderlyingType.FullName);
                }

                return helper.GenerateCollectionWriter(collectionContract);
            }
            finally
            {
                if (TD.DCJsonGenWriterStopIsEnabled())
                {
                    TD.DCJsonGenWriterStop();
                }
            }
        }
        public JsonFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
        {
            try
            {
                if (TD.DCJsonGenReaderStartIsEnabled())
                {
                    TD.DCJsonGenReaderStart("Collection", collectionContract.StableName.Name);
                }

                return helper.GenerateCollectionReader(collectionContract);

            }
            finally
            {
                if (TD.DCJsonGenReaderStopIsEnabled())
                {
                    TD.DCJsonGenReaderStop();
                }
            }

        }
Esempio n. 7
0
 internal JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
 {
     _ilg = new CodeGenerator();
     bool memberAccessFlag = collectionContract.RequiresMemberAccessForWrite(null);
     try
     {
         BeginMethod(_ilg, "Write" + DataContract.SanitizeTypeName(collectionContract.StableName.Name) + "ToJson", typeof(JsonFormatCollectionWriterDelegate), memberAccessFlag);
     }
     catch (SecurityException securityException)
     {
         if (memberAccessFlag)
         {
             collectionContract.RequiresMemberAccessForWrite(securityException);
         }
         else
         {
             throw;
         }
     }
     InitArgs(collectionContract.UnderlyingType);
     WriteCollection(collectionContract);
     return (JsonFormatCollectionWriterDelegate)_ilg.EndMethod();
 }
Esempio n. 8
0
        internal static DataContract GetDataContractFromSurrogateSelector(ISurrogateSelector surrogateSelector, StreamingContext context, RuntimeTypeHandle typeHandle, Type type, ref Hashtable surrogateDataContracts)
        {
            if (surrogateSelector == null)
                return null;

            if (type == null)
                type = Type.GetTypeFromHandle(typeHandle);
            DataContract builtInDataContract = DataContract.GetBuiltInDataContract(type);
            if (builtInDataContract != null)
                return builtInDataContract;
            if (surrogateDataContracts != null)
            {
                DataContract cachedSurrogateContract = (DataContract)surrogateDataContracts[type];
                if (cachedSurrogateContract != null)
                    return cachedSurrogateContract;
            }
            DataContract surrogateContract = null;
            ISerializationSurrogate surrogate = GetSurrogate(type, surrogateSelector, context);
            if (surrogate != null)
                surrogateContract = new SurrogateDataContract(type, surrogate);
            else if (type.IsArray)
            {
                Type elementType = type.GetElementType();
                DataContract itemContract = GetDataContractFromSurrogateSelector(surrogateSelector, context, elementType.TypeHandle, elementType, ref surrogateDataContracts);
                if (itemContract == null)
                    itemContract = DataContract.GetDataContract(elementType.TypeHandle, elementType, SerializationMode.SharedType);
                surrogateContract = new CollectionDataContract(type, itemContract);
            }
            if (surrogateContract != null)
            {
                if (surrogateDataContracts == null)
                    surrogateDataContracts = new Hashtable();
                surrogateDataContracts.Add(type, surrogateContract);
                return surrogateContract;
            }
            return null;
        }
Esempio n. 9
0
 public JsonFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
 {
     return _helper.GenerateGetOnlyCollectionReader(collectionContract);
 }
            void StoreCollectionValue(LocalBuilder collection, LocalBuilder value, CollectionDataContract collectionContract)
            {
                if (collectionContract.Kind == CollectionKind.GenericDictionary || collectionContract.Kind == CollectionKind.Dictionary)
                {
                    ClassDataContract keyValuePairContract = DataContract.GetDataContract(value.LocalType) as ClassDataContract;
                    if (keyValuePairContract == null)
                    {
                        Fx.Assert("Failed to create contract for KeyValuePair type");
                    }
                    DataMember keyMember = keyValuePairContract.Members[0];
                    DataMember valueMember = keyValuePairContract.Members[1];
                    LocalBuilder pairKey = ilg.DeclareLocal(keyMember.MemberType, keyMember.Name);
                    LocalBuilder pairValue = ilg.DeclareLocal(valueMember.MemberType, valueMember.Name);
                    ilg.LoadAddress(value);
                    ilg.LoadMember(keyMember.MemberInfo);
                    ilg.Stloc(pairKey);
                    ilg.LoadAddress(value);
                    ilg.LoadMember(valueMember.MemberInfo);
                    ilg.Stloc(pairValue);

                    ilg.Call(collection, collectionContract.AddMethod, pairKey, pairValue);
                    if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid)
                        ilg.Pop();
                }
                else
                {
                    ilg.Call(collection, collectionContract.AddMethod, value);
                    if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid)
                        ilg.Pop();
                }
            }
            void WriteCollection(CollectionDataContract collectionContract)
            {
                LocalBuilder itemName = ilg.DeclareLocal(typeof(XmlDictionaryString), "itemName");
                ilg.Load(contextArg);
                ilg.LoadMember(JsonFormatGeneratorStatics.CollectionItemNameProperty);
                ilg.Store(itemName);

                if (collectionContract.Kind == CollectionKind.Array)
                {
                    Type itemType = collectionContract.ItemType;
                    LocalBuilder i = ilg.DeclareLocal(Globals.TypeOfInt, "i");

                    ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementArrayCountMethod, xmlWriterArg, objectLocal);

                    if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, objectLocal, itemName))
                    {
                        WriteArrayAttribute();
                        ilg.For(i, 0, objectLocal);
                        if (!TryWritePrimitive(itemType, null /*value*/, null /*memberInfo*/, i /*arrayItemIndex*/, itemName, 0 /*nameIndex*/))
                        {
                            WriteStartElement(itemName, 0 /*nameIndex*/);
                            ilg.LoadArrayElement(objectLocal, i);
                            LocalBuilder memberValue = ilg.DeclareLocal(itemType, "memberValue");
                            ilg.Stloc(memberValue);
                            WriteValue(memberValue);
                            WriteEndElement();
                        }
                        ilg.EndFor();
                    }
                }
                else
                {
                    MethodInfo incrementCollectionCountMethod = null;
                    switch (collectionContract.Kind)
                    {
                        case CollectionKind.Collection:
                        case CollectionKind.List:
                        case CollectionKind.Dictionary:
                            incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
                            break;
                        case CollectionKind.GenericCollection:
                        case CollectionKind.GenericList:
                            incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
                            break;
                        case CollectionKind.GenericDictionary:
                            incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
                            break;
                    }
                    if (incrementCollectionCountMethod != null)
                    {
                        ilg.Call(contextArg, incrementCollectionCountMethod, xmlWriterArg, objectLocal);
                    }

                    bool isDictionary = false, isGenericDictionary = false;
                    Type enumeratorType = null;
                    Type[] keyValueTypes = null;
                    if (collectionContract.Kind == CollectionKind.GenericDictionary)
                    {
                        isGenericDictionary = true;
                        keyValueTypes = collectionContract.ItemType.GetGenericArguments();
                        enumeratorType = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
                    }
                    else if (collectionContract.Kind == CollectionKind.Dictionary)
                    {
                        isDictionary = true;
                        keyValueTypes = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
                        enumeratorType = Globals.TypeOfDictionaryEnumerator;
                    }
                    else
                    {
                        enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
                    }
                    MethodInfo moveNextMethod = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                    MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                    if (moveNextMethod == null || getCurrentMethod == null)
                    {
                        if (enumeratorType.IsInterface)
                        {
                            if (moveNextMethod == null)
                                moveNextMethod = JsonFormatGeneratorStatics.MoveNextMethod;
                            if (getCurrentMethod == null)
                                getCurrentMethod = JsonFormatGeneratorStatics.GetCurrentMethod;
                        }
                        else
                        {
                            Type ienumeratorInterface = Globals.TypeOfIEnumerator;
                            CollectionKind kind = collectionContract.Kind;
                            if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
                            {
                                Type[] interfaceTypes = enumeratorType.GetInterfaces();
                                foreach (Type interfaceType in interfaceTypes)
                                {
                                    if (interfaceType.IsGenericType
                                        && interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric
                                        && interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
                                    {
                                        ienumeratorInterface = interfaceType;
                                        break;
                                    }
                                }
                            }
                            if (moveNextMethod == null)
                                moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
                            if (getCurrentMethod == null)
                                getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
                        }
                    }
                    Type elementType = getCurrentMethod.ReturnType;
                    LocalBuilder currentValue = ilg.DeclareLocal(elementType, "currentValue");

                    LocalBuilder enumerator = ilg.DeclareLocal(enumeratorType, "enumerator");
                    ilg.Call(objectLocal, collectionContract.GetEnumeratorMethod);
                    if (isDictionary)
                    {
                        ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { Globals.TypeOfIDictionaryEnumerator }, null);
                        ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, Globals.TypeOfIDictionaryEnumerator);
                        ilg.New(dictEnumCtor);
                    }
                    else if (isGenericDictionary)
                    {
                        Type ctorParam = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
                        ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
                        ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, ctorParam);
                        ilg.New(dictEnumCtor);
                    }
                    ilg.Stloc(enumerator);

                    bool canWriteSimpleDictionary = isDictionary || isGenericDictionary;
                    if (canWriteSimpleDictionary)
                    {
                        Type genericDictionaryKeyValueType = Globals.TypeOfKeyValue.MakeGenericType(keyValueTypes);
                        PropertyInfo genericDictionaryKeyProperty = genericDictionaryKeyValueType.GetProperty(JsonGlobals.KeyString);
                        PropertyInfo genericDictionaryValueProperty = genericDictionaryKeyValueType.GetProperty(JsonGlobals.ValueString);

                        ilg.Load(contextArg);
                        ilg.LoadMember(JsonFormatGeneratorStatics.UseSimpleDictionaryFormatWriteProperty);
                        ilg.If();
                        WriteObjectAttribute();
                        LocalBuilder pairKey = ilg.DeclareLocal(Globals.TypeOfString, "key");
                        LocalBuilder pairValue = ilg.DeclareLocal(keyValueTypes[1], "value");
                        ilg.ForEach(currentValue, elementType, enumeratorType, enumerator, getCurrentMethod);

                        ilg.LoadAddress(currentValue);
                        ilg.LoadMember(genericDictionaryKeyProperty);
                        ilg.ToString(keyValueTypes[0]);
                        ilg.Stloc(pairKey);

                        ilg.LoadAddress(currentValue);
                        ilg.LoadMember(genericDictionaryValueProperty);
                        ilg.Stloc(pairValue);

                        WriteStartElement(pairKey, 0 /*nameIndex*/);
                        WriteValue(pairValue);
                        WriteEndElement();

                        ilg.EndForEach(moveNextMethod);
                        ilg.Else();
                    }

                    WriteArrayAttribute();

                    ilg.ForEach(currentValue, elementType, enumeratorType, enumerator, getCurrentMethod);
                    if (incrementCollectionCountMethod == null)
                    {
                        ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
                    }
                    if (!TryWritePrimitive(elementType, currentValue, null /*memberInfo*/, null /*arrayItemIndex*/, itemName, 0 /*nameIndex*/))
                    {
                        WriteStartElement(itemName, 0 /*nameIndex*/);

                        if (isGenericDictionary || isDictionary)
                        {
                            ilg.Call(dataContractArg, JsonFormatGeneratorStatics.GetItemContractMethod);
                            ilg.Call(JsonFormatGeneratorStatics.GetRevisedItemContractMethod);
                            ilg.Call(JsonFormatGeneratorStatics.GetJsonDataContractMethod);
                            ilg.Load(xmlWriterArg);
                            ilg.Load(currentValue);
                            ilg.ConvertValue(currentValue.LocalType, Globals.TypeOfObject);
                            ilg.Load(contextArg);
                            ilg.Load(currentValue.LocalType);
                            ilg.LoadMember(JsonFormatGeneratorStatics.TypeHandleProperty);
                            ilg.Call(JsonFormatGeneratorStatics.WriteJsonValueMethod);
                        }
                        else
                        {
                            WriteValue(currentValue);
                        }
                        WriteEndElement();
                    }
                    ilg.EndForEach(moveNextMethod);

                    if (canWriteSimpleDictionary)
                    {
                        ilg.EndIf();
                    }
                }
            }
            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
                {
                    LocalBuilder nodeType = ilg.DeclareLocal(typeof(XmlNodeType), "nodeType");

                    ilg.BeginWhileCondition();
                    ilg.Call(xmlReaderArg, JsonFormatGeneratorStatics.MoveToContentMethod);
                    ilg.Stloc(nodeType);
                    ilg.Load(nodeType);
                    ilg.Load(XmlNodeType.EndElement);
                    ilg.BeginWhileBody(Cmp.NotEqualTo);

                    ilg.Load(nodeType);
                    ilg.Load(XmlNodeType.Element);
                    ilg.If(Cmp.NotEqualTo);
                    ThrowUnexpectedStateException(XmlNodeType.Element);
                    ilg.EndIf();

                    ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);

                    if (keyParseMode == KeyParseMode.UsingParseEnum)
                    {
                        ilg.Load(keyType);
                    }

                    ilg.Load(xmlReaderArg);
                    ilg.Call(JsonFormatGeneratorStatics.GetJsonMemberNameMethod);

                    if (keyParseMode == KeyParseMode.UsingParseEnum)
                    {
                        ilg.Call(JsonFormatGeneratorStatics.ParseEnumMethod);
                        ilg.ConvertValue(Globals.TypeOfObject, keyType);
                    }
                    else if (keyParseMode == KeyParseMode.UsingCustomParse)
                    {
                        ilg.Call(keyDataContract.ParseMethod);
                    }
                    LocalBuilder pairKey = ilg.DeclareLocal(keyType, "key");
                    ilg.Stloc(pairKey);
                    if (keyTypeNullableDepth > 0)
                    {
                        LocalBuilder pairKeyNullable = ilg.DeclareLocal(keyTypeOriginal, "keyOriginal");
                        WrapNullableObject(pairKey, pairKeyNullable, keyTypeNullableDepth);
                        pairKey = pairKeyNullable;
                    }

                    LocalBuilder pairValue = ReadValue(valueType, String.Empty);
                    StoreKeyValuePair(objectLocal, collectionContract, pairKey, pairValue);

                    ilg.EndWhile();
                }
            }
            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, null, Globals.EmptyTypeArray, null);
                            break;
                        case CollectionKind.Dictionary:
                            type = Globals.TypeOfHashtable;
                            constructor = XmlFormatGeneratorStatics.HashtableCtor;
                            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;
                    }
                }
                string itemName = collectionContract.ItemName;
                string itemNs = collectionContract.StableName.Namespace;

                objectLocal = ilg.DeclareLocal(type, "objectDeserialized");
                if (!isArray)
                {
                    if (type.IsValueType)
                    {
                        ilg.Ldloca(objectLocal);
                        ilg.InitObj(type);
                    }
                    else
                    {
                        ilg.New(constructor);
                        ilg.Stloc(objectLocal);
                        ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal);
                    }
                }

                LocalBuilder size = ilg.DeclareLocal(Globals.TypeOfInt, "arraySize");
                ilg.Call(contextArg, XmlFormatGeneratorStatics.GetArraySizeMethod);
                ilg.Stloc(size);

                LocalBuilder objectId = ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead");
                ilg.Call(contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod);
                ilg.Stloc(objectId);

                bool canReadPrimitiveArray = false;
                if (isArray && TryReadPrimitiveArray(type, itemType, size))
                {
                    canReadPrimitiveArray = true;
                    ilg.IfNot();
                }

                ilg.If(size, Cmp.EqualTo, -1);

                LocalBuilder growingCollection = null;
                if (isArray)
                {
                    growingCollection = ilg.DeclareLocal(type, "growingCollection");
                    ilg.NewArray(itemType, 32);
                    ilg.Stloc(growingCollection);
                }
                LocalBuilder i = ilg.DeclareLocal(Globals.TypeOfInt, "i");
                object forLoop = ilg.For(i, 0, Int32.MaxValue);
                IsStartElement(memberNamesArg, memberNamespacesArg);
                ilg.If();
                ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
                LocalBuilder value = ReadCollectionItem(collectionContract, itemType, itemName, itemNs);
                if (isArray)
                {
                    MethodInfo ensureArraySizeMethod = XmlFormatGeneratorStatics.EnsureArraySizeMethod.MakeGenericMethod(itemType);
                    ilg.Call(null, ensureArraySizeMethod, growingCollection, i);
                    ilg.Stloc(growingCollection);
                    ilg.StoreArrayElement(growingCollection, i, value);
                }
                else
                    StoreCollectionValue(objectLocal, value, collectionContract);
                ilg.Else();
                IsEndElement();
                ilg.If();
                ilg.Break(forLoop);
                ilg.Else();
                HandleUnexpectedItemInCollection(i);
                ilg.EndIf();
                ilg.EndIf();

                ilg.EndFor();
                if (isArray)
                {
                    MethodInfo trimArraySizeMethod = XmlFormatGeneratorStatics.TrimArraySizeMethod.MakeGenericMethod(itemType);
                    ilg.Call(null, trimArraySizeMethod, growingCollection, i);
                    ilg.Stloc(objectLocal);
                    ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectWithIdMethod, objectId, objectLocal);
                }
                ilg.Else();

                ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, size);
                if (isArray)
                {
                    ilg.NewArray(itemType, size);
                    ilg.Stloc(objectLocal);
                    ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal);
                }
                LocalBuilder j = ilg.DeclareLocal(Globals.TypeOfInt, "j");
                ilg.For(j, 0, size);
                IsStartElement(memberNamesArg, memberNamespacesArg);
                ilg.If();
                LocalBuilder itemValue = ReadCollectionItem(collectionContract, itemType, itemName, itemNs);
                if (isArray)
                    ilg.StoreArrayElement(objectLocal, j, itemValue);
                else
                    StoreCollectionValue(objectLocal, itemValue, collectionContract);
                ilg.Else();
                HandleUnexpectedItemInCollection(j);
                ilg.EndIf();
                ilg.EndFor();
                ilg.Call(contextArg, XmlFormatGeneratorStatics.CheckEndOfArrayMethod, xmlReaderArg, size, memberNamesArg, memberNamespacesArg);
                ilg.EndIf();

                if (canReadPrimitiveArray)
                {
                    ilg.Else();
                    ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectWithIdMethod, objectId, objectLocal);
                    ilg.EndIf();
                }
            }
        private void ReadSimpleDictionary(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, CollectionDataContract collectionContract, Type keyValueType, object dictionary)
        {
            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)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                          new InvalidOperationException(
                              SR.Format(SR.KeyTypeCannotBeParsedInSimpleDictionary,
                                        DataContract.GetClrTypeFullName(collectionContract.UnderlyingType),
                                        DataContract.GetClrTypeFullName(keyType))
                              ));
            }

            while (true)
            {
                XmlNodeType nodeType = xmlReader.MoveToContent();
                if (nodeType == XmlNodeType.EndElement)
                {
                    return;
                }
                if (nodeType != XmlNodeType.Element)
                {
                    throw XmlObjectSerializerReadContext.CreateUnexpectedStateException(XmlNodeType.Element, xmlReader);
                }

                context.IncrementItemCount(1);
                string keyString = XmlObjectSerializerReadContextComplexJson.GetJsonMemberName(xmlReader);
                object pairKey;

                if (keyParseMode == KeyParseMode.UsingParseEnum)
                {
                    pairKey = Enum.Parse(keyType, keyString);
                }
                else if (keyParseMode == KeyParseMode.UsingCustomParse)
                {
                    pairKey = keyDataContract.ParseMethod.Invoke(null, new object[] { keyString });
                }
                else
                {
                    pairKey = keyString;
                }

                if (keyTypeNullableDepth > 0)
                {
                    throw new NotImplementedException("keyTypeNullableDepth > 0");
                }

                object pairValue = ReflectionReadValue(xmlReader, context, valueType, string.Empty, string.Empty);


                ((IDictionary)dictionary).Add(pairKey, pairValue);
            }
        }
		public JsonFormatWriterInterpreter (CollectionDataContract collectionContract)
		{
			this.collectionContract = collectionContract;
		}
        protected virtual void SerializeWithXsiType(XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
        {
            bool verifyKnownType = false;

#if !NET_NATIVE
            DataContract dataContract;
            if (declaredType.GetTypeInfo().IsInterface&& CollectionDataContract.IsCollectionInterface(declaredType))
            {
                dataContract = GetDataContractSkipValidation(DataContract.GetId(objectTypeHandle), objectTypeHandle, objectType);
                if (OnHandleIsReference(xmlWriter, dataContract, obj))
                {
                    return;
                }
                dataContract = GetDataContract(declaredTypeHandle, declaredType);
#else
            DataContract dataContract = DataContract.GetDataContractFromGeneratedAssembly(declaredType);
            if (dataContract.TypeIsInterface && dataContract.TypeIsCollectionInterface)
            {
                if (OnHandleIsReference(xmlWriter, dataContract, obj))
                {
                    return;
                }
                if (this.Mode == SerializationMode.SharedType && dataContract.IsValidContract(this.Mode))
                {
                    dataContract = dataContract.GetValidContract(this.Mode);
                }
                else
                {
                    dataContract = GetDataContract(declaredTypeHandle, declaredType);
                }
#endif
                if (!WriteClrTypeInfo(xmlWriter, dataContract) && DataContractResolver != null)
                {
                    if (objectType == null)
                    {
                        objectType = Type.GetTypeFromHandle(objectTypeHandle);
                    }
                    WriteResolvedTypeInfo(xmlWriter, objectType, declaredType);
                }
            }
            else if (declaredType.IsArray)//Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item
            {
                // A call to OnHandleIsReference is not necessary here -- arrays cannot be IsReference
                dataContract = GetDataContract(objectTypeHandle, objectType);
                WriteClrTypeInfo(xmlWriter, dataContract);
                dataContract = GetDataContract(declaredTypeHandle, declaredType);
            }
            else
            {
                dataContract = GetDataContract(objectTypeHandle, objectType);
                if (OnHandleIsReference(xmlWriter, dataContract, obj))
                {
                    return;
                }
                if (!WriteClrTypeInfo(xmlWriter, dataContract))
                {
                    DataContract declaredTypeContract = (declaredTypeID >= 0)
                        ? GetDataContract(declaredTypeID, declaredTypeHandle)
                        : GetDataContract(declaredTypeHandle, declaredType);
                    verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, declaredTypeContract);
                }
            }

            SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, declaredTypeHandle, declaredType);
        }
        protected override bool ReflectionReadSpecialCollection(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, CollectionDataContract collectionContract, object resultCollection)
        {
            var jsonContext = context as XmlObjectSerializerReadContextComplexJson;

            Debug.Assert(jsonContext != null);

            bool canReadSimpleDictionary = collectionContract.Kind == CollectionKind.Dictionary ||
                                           collectionContract.Kind == CollectionKind.GenericDictionary;

            if (canReadSimpleDictionary && jsonContext.UseSimpleDictionaryFormat)
            {
                ReadSimpleDictionary(xmlReader, context, collectionContract, collectionContract.ItemType, resultCollection);
            }

            return(false);
        }
Esempio n. 18
0
        public void WriteCollectionToXml(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context, CollectionDataContract collectionContract)
        {
            this.writer       = xmlWriter;
            this.obj          = obj;
            this.ctx          = context;
            this.dataContract = collectionContract;

            InitArgs(collectionContract.UnderlyingType);

            // DemandMemberAccessPermission(memberAccessFlag);
            if (collectionContract.IsReadOnlyContract)
            {
                DataContract.ThrowInvalidDataContractException(collectionContract.SerializationExceptionMessage, null);
            }

            WriteCollection(collectionContract);
        }
Esempio n. 19
0
 public XmlFormatWriterInterpreter(CollectionDataContract collectionContract)
 {
     this.collectionContract = collectionContract;
 }
Esempio n. 20
0
 internal XmlFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
 {
     return((XmlWriterDelegator xw, object obj, XmlObjectSerializerWriteContext ctx, CollectionDataContract ctr) => new XmlFormatWriterInterpreter(collectionContract).WriteCollectionToXml(xw, obj, ctx, ctr));
 }
Esempio n. 21
0
            private void ReadGetOnlyCollection(CollectionDataContract collectionContract)
            {
                Type type = collectionContract.UnderlyingType;
                Type itemType = collectionContract.ItemType;
                bool isArray = (collectionContract.Kind == CollectionKind.Array);
                LocalBuilder size = _ilg.DeclareLocal(Globals.TypeOfInt, "arraySize");

                _objectLocal = _ilg.DeclareLocal(type, "objectDeserialized");
                _ilg.Load(_contextArg);
                _ilg.LoadMember(XmlFormatGeneratorStatics.GetCollectionMemberMethod);
                _ilg.ConvertValue(Globals.TypeOfObject, type);
                _ilg.Stloc(_objectLocal);

                bool canReadSimpleDictionary = collectionContract.Kind == CollectionKind.Dictionary ||
                                               collectionContract.Kind == CollectionKind.GenericDictionary;
                if (canReadSimpleDictionary)
                {
                    _ilg.Load(_contextArg);
                    _ilg.LoadMember(JsonFormatGeneratorStatics.UseSimpleDictionaryFormatReadProperty);
                    _ilg.If();

                    if (!type.GetTypeInfo().IsValueType)
                    {
                        _ilg.If(_objectLocal, Cmp.EqualTo, null);
                        _ilg.Call(null, XmlFormatGeneratorStatics.ThrowNullValueReturnedForGetOnlyCollectionExceptionMethod, type);
                        _ilg.EndIf();
                    }

                    ReadSimpleDictionary(collectionContract, itemType);

                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.CheckEndOfArrayMethod, _xmlReaderArg, size, _memberNamesArg, _emptyDictionaryStringArg);

                    _ilg.Else();
                }

                //check that items are actually going to be deserialized into the collection
                IsStartElement(_memberNamesArg, _emptyDictionaryStringArg);
                _ilg.If();

                if (!type.GetTypeInfo().IsValueType)
                {
                    _ilg.If(_objectLocal, Cmp.EqualTo, null);
                    _ilg.Call(null, XmlFormatGeneratorStatics.ThrowNullValueReturnedForGetOnlyCollectionExceptionMethod, type);
                    _ilg.EndIf();
                }

                if (isArray)
                {
                    _ilg.Load(_objectLocal);
                    _ilg.Call(XmlFormatGeneratorStatics.GetArrayLengthMethod);
                    _ilg.Stloc(size);
                }

                LocalBuilder i = _ilg.DeclareLocal(Globals.TypeOfInt, "i");
                object forLoop = _ilg.For(i, 0, Int32.MaxValue);
                IsStartElement(_memberNamesArg, _emptyDictionaryStringArg);
                _ilg.If();
                _ilg.Call(_contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
                LocalBuilder value = ReadCollectionItem(collectionContract, itemType);
                if (isArray)
                {
                    _ilg.If(size, Cmp.EqualTo, i);
                    _ilg.Call(null, XmlFormatGeneratorStatics.ThrowArrayExceededSizeExceptionMethod, size, type);
                    _ilg.Else();
                    _ilg.StoreArrayElement(_objectLocal, i, value);
                    _ilg.EndIf();
                }
                else
                    StoreCollectionValue(_objectLocal, value, collectionContract);
                _ilg.Else();
                IsEndElement();
                _ilg.If();
                _ilg.Break(forLoop);
                _ilg.Else();
                HandleUnexpectedItemInCollection(i);
                _ilg.EndIf();
                _ilg.EndIf();
                _ilg.EndFor();
                _ilg.Call(_contextArg, XmlFormatGeneratorStatics.CheckEndOfArrayMethod, _xmlReaderArg, size, _memberNamesArg, _emptyDictionaryStringArg);

                _ilg.EndIf();

                if (canReadSimpleDictionary)
                {
                    _ilg.EndIf();
                }
            }
 public void ReflectionReadGetOnlyCollection(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContextComplexJson context, XmlDictionaryString emptyDictionaryString, XmlDictionaryString itemName, CollectionDataContract collectionContract)
 {
     _reflectionReader.ReflectionReadGetOnlyCollection(xmlReader, context, itemName, emptyDictionaryString /*itemNamespace*/, collectionContract);
 }
		void WriteCollection(CollectionDataContract collectionContract)
		{
			XmlDictionaryString itemName = context.CollectionItemName;

			if (collectionContract.Kind == CollectionKind.Array)
			{
				Type itemType = collectionContract.ItemType;
				int i;

				// This check does not exist in the original dynamic code,
				// but there is no other way to check type mismatch.
				// CollectionSerialization.ArrayContract() shows that it is required.
				if (objLocal.GetType ().GetElementType () != itemType)
					throw new InvalidCastException (string.Format ("Cannot cast array of {0} to array of {1}", objLocal.GetType ().GetElementType (), itemType));

				context.IncrementArrayCount (writer, (Array) objLocal);

				if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, () => objLocal, itemName))
				{
					WriteArrayAttribute ();
					var arr = (Array) objLocal;
					var idx = new int [1];
					for (i = 0; i < arr.Length; i++) {
						if (!TryWritePrimitive(itemType, null, null, i, itemName, 0)) {
							WriteStartElement (itemName, 0);
							idx [0] = i;
							var mbrVal = arr.GetValue (idx);
							WriteValue (itemType, mbrVal);
							WriteEndElement ();
						}
					}
				}
			}
			else
			{
				// This check does not exist in the original dynamic code,
				// but there is no other way to check type mismatch.
				// CollectionSerialization.ArrayContract() shows that it is required.
				if (!collectionContract.UnderlyingType.IsAssignableFrom (objLocal.GetType ()))
					throw new InvalidCastException (string.Format ("Cannot cast {0} to {1}", objLocal.GetType (), collectionContract.UnderlyingType));
				
				MethodInfo incrementCollectionCountMethod = null;
				switch (collectionContract.Kind)
				{
				case CollectionKind.Collection:
				case CollectionKind.List:
				case CollectionKind.Dictionary:
					incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
					break;
				case CollectionKind.GenericCollection:
				case CollectionKind.GenericList:
					incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
					break;
				case CollectionKind.GenericDictionary:
					incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
					break;
				}
				if (incrementCollectionCountMethod != null)
					incrementCollectionCountMethod.Invoke (context, new object [] {writer, objLocal});

				bool isDictionary = false, isGenericDictionary = false;
				Type enumeratorType = null;
				Type [] keyValueTypes = null;
				if (collectionContract.Kind == CollectionKind.GenericDictionary)
				{
					isGenericDictionary = true;
					keyValueTypes = collectionContract.ItemType.GetGenericArguments ();
					enumeratorType = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType (keyValueTypes);
				}
				else if (collectionContract.Kind == CollectionKind.Dictionary)
				{
					isDictionary = true;
					keyValueTypes = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
					enumeratorType = Globals.TypeOfDictionaryEnumerator;
				}
				else
				{
					enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
				}
				MethodInfo moveNextMethod = enumeratorType.GetMethod (Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
				MethodInfo getCurrentMethod = enumeratorType.GetMethod (Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
				if (moveNextMethod == null || getCurrentMethod == null)
				{
					if (enumeratorType.IsInterface)
					{
						if (moveNextMethod == null)
							moveNextMethod = JsonFormatGeneratorStatics.MoveNextMethod;
						if (getCurrentMethod == null)
							getCurrentMethod = JsonFormatGeneratorStatics.GetCurrentMethod;
					}
					else
					{
						Type ienumeratorInterface = Globals.TypeOfIEnumerator;
						CollectionKind kind = collectionContract.Kind;
						if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
						{
							Type[] interfaceTypes = enumeratorType.GetInterfaces();
							foreach (Type interfaceType in interfaceTypes)
							{
								if (interfaceType.IsGenericType
									&& interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric
									&& interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
								{
									ienumeratorInterface = interfaceType;
									break;
								}
							}
						}
						if (moveNextMethod == null)
							moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
						if (getCurrentMethod == null)
							getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
					}
				}
				Type elementType = getCurrentMethod.ReturnType;
				object currentValue = null; // of elementType

				var enumerator = (IEnumerator) collectionContract.GetEnumeratorMethod.Invoke (objLocal, new object [0]);
				if (isDictionary)
				{
					ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor (Globals.ScanAllMembers, null, new Type[] { Globals.TypeOfIDictionaryEnumerator }, null);
					enumerator = (IEnumerator) dictEnumCtor.Invoke (new object [] {enumerator});
				}
				else if (isGenericDictionary)
				{
					Type ctorParam = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
					ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
					enumerator = (IEnumerator) Activator.CreateInstance (enumeratorType, new object [] {enumerator});
				}

				bool canWriteSimpleDictionary = isDictionary || isGenericDictionary;
				
				bool writeSimpleDictionary = canWriteSimpleDictionary && context.UseSimpleDictionaryFormat;
				PropertyInfo genericDictionaryKeyProperty = null, genericDictionaryValueProperty = null;
				
				if (canWriteSimpleDictionary)
				{
					Type genericDictionaryKeyValueType = Globals.TypeOfKeyValue.MakeGenericType (keyValueTypes);
					genericDictionaryKeyProperty = genericDictionaryKeyValueType.GetProperty (JsonGlobals.KeyString);
					genericDictionaryValueProperty = genericDictionaryKeyValueType.GetProperty (JsonGlobals.ValueString);
				}

				if (writeSimpleDictionary) {
					WriteObjectAttribute ();
					object key, value;
					var empty_args = new object [0];
					while ((bool) moveNextMethod.Invoke (enumerator, empty_args)) {
						currentValue = getCurrentMethod.Invoke (enumerator, empty_args);
						key = CodeInterpreter.GetMember (genericDictionaryKeyProperty, currentValue);
						value = CodeInterpreter.GetMember (genericDictionaryValueProperty, currentValue);

						WriteStartElement (key, 0 /*nameIndex*/);
						WriteValue (genericDictionaryValueProperty.PropertyType, value);
						WriteEndElement ();
					}
				} else {
					WriteArrayAttribute ();

					var emptyArray = new object [0];
					while (enumerator != null && enumerator.MoveNext ()) {
						currentValue = getCurrentMethod.Invoke (enumerator, emptyArray);

						if (incrementCollectionCountMethod == null)
							XmlFormatGeneratorStatics.IncrementItemCountMethod.Invoke (context, new object [] {1});

						if (!TryWritePrimitive (elementType, () => currentValue, null, null, itemName, 0))
						{
							WriteStartElement (itemName, 0);
							if (isGenericDictionary || isDictionary) {
								var jc = JsonDataContract.GetJsonDataContract (XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract (
								collectionDataContract.ItemContract));
								// FIXME: this TypeHandle might be wrong; there is no easy way to get Type for currentValue though.
								DataContractJsonSerializer.WriteJsonValue (jc, writer, currentValue, context, currentValue.GetType ().TypeHandle);
							}
							else
								WriteValue (elementType, currentValue);
							WriteEndElement ();
						}
					}
				}
			}
		}
 protected override string GetCollectionContractItemName(CollectionDataContract collectionContract)
 {
     return(JsonGlobals.itemString);
 }
 void StoreKeyValuePair(LocalBuilder collection, CollectionDataContract collectionContract, LocalBuilder pairKey, LocalBuilder pairValue)
 {
     ilg.Call(collection, collectionContract.AddMethod, pairKey, pairValue);
     if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid)
         ilg.Pop();
 }
 protected override string GetCollectionContractNamespace(CollectionDataContract collectionContract)
 {
     return(string.Empty);
 }
 public XmlFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
 {
     ilg = GenerateCollectionReaderHelper(collectionContract, true /*isGetOnlyCollection*/);
     ReadGetOnlyCollection(collectionContract);
     return (XmlFormatGetOnlyCollectionReaderDelegate)ilg.EndMethod();
 }
        protected override object ReflectionReadDictionaryItem(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, CollectionDataContract collectionContract)
        {
            var jsonContext = context as XmlObjectSerializerReadContextComplexJson;

            Debug.Assert(jsonContext != null);
            Debug.Assert(collectionContract.Kind == CollectionKind.Dictionary || collectionContract.Kind == CollectionKind.GenericDictionary);
            context.ReadAttributes(xmlReader);

            var itemContract = XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract(collectionContract.ItemContract);

            return(DataContractJsonSerializer.ReadJsonValue(itemContract, xmlReader, jsonContext));
        }
 LocalBuilder ReadCollectionItem(CollectionDataContract collectionContract, Type itemType, string itemName, string itemNs)
 {
     if (collectionContract.Kind == CollectionKind.Dictionary || collectionContract.Kind == CollectionKind.GenericDictionary)
     {
         ilg.Call(contextArg, XmlFormatGeneratorStatics.ResetAttributesMethod);
         LocalBuilder value = ilg.DeclareLocal(itemType, "valueRead");
         ilg.Load(collectionContractArg);
         ilg.Call(XmlFormatGeneratorStatics.GetItemContractMethod);
         ilg.Load(xmlReaderArg);
         ilg.Load(contextArg);
         ilg.Call(XmlFormatGeneratorStatics.ReadXmlValueMethod);
         ilg.ConvertValue(Globals.TypeOfObject, itemType);
         ilg.Stloc(value);
         return value;
     }
     else
     {
         return ReadValue(itemType, itemName, itemNs);
     }
 }
Esempio n. 30
0
        private object ReadCollectionItems(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, XmlDictionaryString collectionItemName, XmlDictionaryString collectionItemNamespace, CollectionDataContract collectionContract, object resultCollection, bool isReadOnlyCollection)
        {
            string itemName = GetCollectionContractItemName(collectionContract);
            string itemNs   = GetCollectionContractNamespace(collectionContract);
            Type   itemType = collectionContract.ItemType;
            CollectionReadItemDelegate collectionReadItemDelegate = GetCollectionReadItemDelegate(collectionContract);
            MethodInfo getCollectionSetItemDelegateMethod         = s_getCollectionSetItemDelegateMethod.MakeGenericMethod(itemType);
            CollectionSetItemDelegate collectionSetItemDelegate   = (CollectionSetItemDelegate)getCollectionSetItemDelegateMethod.Invoke(this, new object[] { collectionContract, resultCollection, isReadOnlyCollection });

            int index = 0;

            while (true)
            {
                if (xmlReader.IsStartElement(collectionItemName, collectionItemNamespace))
                {
                    object collectionItem = collectionReadItemDelegate(xmlReader, context, collectionContract, itemType, itemName, itemNs);
                    resultCollection = collectionSetItemDelegate(resultCollection, collectionItem, index);
                    index++;
                }
                else
                {
                    if (xmlReader.NodeType == XmlNodeType.EndElement)
                    {
                        break;
                    }

                    if (!xmlReader.IsStartElement())
                    {
                        throw XmlObjectSerializerReadContext.CreateUnexpectedStateException(XmlNodeType.Element, xmlReader);
                    }

                    context.SkipUnknownElement(xmlReader);
                }
            }

            context.IncrementItemCount(index);

            if (!isReadOnlyCollection && IsArrayLikeCollection(collectionContract))
            {
                MethodInfo trimArraySizeMethod = XmlFormatGeneratorStatics.TrimArraySizeMethod.MakeGenericMethod(itemType);
                resultCollection = trimArraySizeMethod.Invoke(null, new object[] { resultCollection, index });
            }

            return(resultCollection);
        }
 internal JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
 {
     ilg = new CodeGenerator();
     bool memberAccessFlag = collectionContract.RequiresMemberAccessForWrite(null);
     try
     {
         BeginMethod(ilg, "Write" + collectionContract.StableName.Name + "ToJson", typeof(JsonFormatCollectionWriterDelegate), memberAccessFlag);
     }
     catch (SecurityException securityException)
     {
         if (memberAccessFlag && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
         {
             collectionContract.RequiresMemberAccessForWrite(securityException);
         }
         else
         {
             throw;
         }
     }
     InitArgs(collectionContract.UnderlyingType);
     DemandMemberAccessPermission(memberAccessFlag);
     if (collectionContract.IsReadOnlyContract)
     {
         ThrowIfCannotSerializeReadOnlyTypes(collectionContract);
     }
     WriteCollection(collectionContract);
     return (JsonFormatCollectionWriterDelegate)ilg.EndMethod();
 }
Esempio n. 32
0
 protected abstract object ReflectionReadDictionaryItem(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, CollectionDataContract collectionContract);
Esempio n. 33
0
        void WriteCollection(CollectionDataContract collectionContract)
        {
            XmlDictionaryString itemNamespace = dataContract.Namespace;

            XmlDictionaryString itemName = collectionDataContract.CollectionItemName;

            if (collectionContract.ChildElementNamespace != null)
            {
                writer.WriteNamespaceDecl(collectionDataContract.ChildElementNamespace);
            }

            if (collectionContract.Kind == CollectionKind.Array)
            {
                Type itemType = collectionContract.ItemType;
                int  i;

                // This check does not exist in the original dynamic code,
                // but there is no other way to check type mismatch.
                // CollectionSerialization.ArrayContract() shows that it is required.
                if (objLocal.GetType().GetElementType() != itemType)
                {
                    throw new InvalidCastException(string.Format("Cannot cast array of {0} to array of {1}", objLocal.GetType().GetElementType(), itemType));
                }

                ctx.IncrementArrayCount(writer, (Array)objLocal);

                if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, () => objLocal, itemName, itemNamespace))
                {
                    var arr = (Array)objLocal;
                    var idx = new int [1];
                    for (i = 0; i < arr.Length; i++)
                    {
                        if (!TryWritePrimitive(itemType, null, null, i, itemNamespace, itemName, 0))
                        {
                            WriteStartElement(itemType, collectionContract.Namespace, itemNamespace, itemName, 0);
                            idx [0] = i;
                            var mbrVal = arr.GetValue(idx);
                            WriteValue(itemType, mbrVal, false);
                            WriteEndElement();
                        }
                    }
                }
            }
            else
            {
                // This check does not exist in the original dynamic code,
                // but there is no other way to check type mismatch.
                // CollectionSerialization.ArrayContract() shows that it is required.
                if (!collectionContract.UnderlyingType.IsAssignableFrom(objLocal.GetType()))
                {
                    throw new InvalidCastException(string.Format("Cannot cast {0} to {1}", objLocal.GetType(), collectionContract.UnderlyingType));
                }

                MethodInfo incrementCollectionCountMethod = null;
                switch (collectionContract.Kind)
                {
                case CollectionKind.Collection:
                case CollectionKind.List:
                case CollectionKind.Dictionary:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
                    break;

                case CollectionKind.GenericCollection:
                case CollectionKind.GenericList:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
                    break;

                case CollectionKind.GenericDictionary:
                    incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
                    break;
                }
                if (incrementCollectionCountMethod != null)
                {
                    incrementCollectionCountMethod.Invoke(ctx, new object [] { writer, objLocal });
                }

                bool    isDictionary = false, isGenericDictionary = false;
                Type    enumeratorType = null;
                Type [] keyValueTypes  = null;
                if (collectionContract.Kind == CollectionKind.GenericDictionary)
                {
                    isGenericDictionary = true;
                    keyValueTypes       = collectionContract.ItemType.GetGenericArguments();
                    enumeratorType      = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
                }
                else if (collectionContract.Kind == CollectionKind.Dictionary)
                {
                    isDictionary   = true;
                    keyValueTypes  = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
                    enumeratorType = Globals.TypeOfDictionaryEnumerator;
                }
                else
                {
                    enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
                }
                MethodInfo moveNextMethod   = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                if (moveNextMethod == null || getCurrentMethod == null)
                {
                    if (enumeratorType.IsInterface)
                    {
                        if (moveNextMethod == null)
                        {
                            moveNextMethod = XmlFormatGeneratorStatics.MoveNextMethod;
                        }
                        if (getCurrentMethod == null)
                        {
                            getCurrentMethod = XmlFormatGeneratorStatics.GetCurrentMethod;
                        }
                    }
                    else
                    {
                        Type           ienumeratorInterface = Globals.TypeOfIEnumerator;
                        CollectionKind kind = collectionContract.Kind;
                        if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
                        {
                            Type[] interfaceTypes = enumeratorType.GetInterfaces();
                            foreach (Type interfaceType in interfaceTypes)
                            {
                                if (interfaceType.IsGenericType &&
                                    interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric &&
                                    interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
                                {
                                    ienumeratorInterface = interfaceType;
                                    break;
                                }
                            }
                        }
                        if (moveNextMethod == null)
                        {
                            moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
                        }
                        if (getCurrentMethod == null)
                        {
                            getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
                        }
                    }
                }
                Type   elementType  = getCurrentMethod.ReturnType;
                object currentValue = null;                 // of elementType

                var enumerator = (IEnumerator)collectionContract.GetEnumeratorMethod.Invoke(objLocal, new object [0]);
                if (isDictionary)
                {
                    enumerator = new CollectionDataContract.DictionaryEnumerator((IDictionaryEnumerator)enumerator);
                }
                else if (isGenericDictionary)
                {
                    Type            ctorParam    = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
                    ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
                    enumerator = (IEnumerator)Activator.CreateInstance(enumeratorType, new object [] { enumerator });
                }

                var emptyArray = new object [0];
                while (enumerator != null && enumerator.MoveNext())
                {
                    currentValue = getCurrentMethod.Invoke(enumerator, emptyArray);

                    if (incrementCollectionCountMethod == null)
                    {
                        XmlFormatGeneratorStatics.IncrementItemCountMethod.Invoke(ctx, new object [] { 1 });
                    }

                    if (!TryWritePrimitive(elementType, () => currentValue, null, null, itemNamespace, itemName, 0))
                    {
                        WriteStartElement(elementType, collectionContract.Namespace, itemNamespace, itemName, 0);
                        if (isGenericDictionary || isDictionary)
                        {
                            collectionDataContract.ItemContract.WriteXmlValue(writer, currentValue, ctx);
                        }
                        else
                        {
                            WriteValue(elementType, currentValue, false);
                        }
                        WriteEndElement();
                    }
                }
            }
        }
Esempio n. 34
0
 protected abstract string GetCollectionContractItemName(CollectionDataContract collectionContract);
Esempio n. 35
0
 private CodeGenerator GenerateCollectionReaderHelper(CollectionDataContract collectionContract, bool isGetOnlyCollection)
 {
     _ilg = new CodeGenerator();
     bool memberAccessFlag = collectionContract.RequiresMemberAccessForRead(null);
     try
     {
         if (isGetOnlyCollection)
         {
             BeginMethod(_ilg, "Read" + DataContract.SanitizeTypeName(collectionContract.StableName.Name) + "FromJson" + "IsGetOnly", typeof(JsonFormatGetOnlyCollectionReaderDelegate), memberAccessFlag);
         }
         else
         {
             BeginMethod(_ilg, "Read" + DataContract.SanitizeTypeName(collectionContract.StableName.Name) + "FromJson", typeof(JsonFormatCollectionReaderDelegate), memberAccessFlag);
         }
     }
     catch (SecurityException securityException)
     {
         if (memberAccessFlag)
         {
             collectionContract.RequiresMemberAccessForRead(securityException);
         }
         else
         {
             throw;
         }
     }
     InitArgs();
     _collectionContractArg = _ilg.GetArg(4);
     return _ilg;
 }
Esempio n. 36
0
 protected abstract string GetCollectionContractNamespace(CollectionDataContract collectionContract);
Esempio n. 37
0
            private void ReadCollection(CollectionDataContract collectionContract)
            {
                Type type = collectionContract.UnderlyingType;
                Type itemType = collectionContract.ItemType;
                bool isArray = (collectionContract.Kind == CollectionKind.Array);
                ConstructorInfo constructor = collectionContract.Constructor;
                if (type.GetTypeInfo().IsInterface)
                {
                    switch (collectionContract.Kind)
                    {
                        case CollectionKind.GenericDictionary:
                            type = Globals.TypeOfDictionaryGeneric.MakeGenericType(itemType.GetGenericArguments());
                            constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Array.Empty<Type>());
                            break;
                        case CollectionKind.Dictionary:
                            type = Globals.TypeOfHashtable;
                            constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, Array.Empty<Type>());
                            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;
                    }
                }

                _objectLocal = _ilg.DeclareLocal(type, "objectDeserialized");
                if (!isArray)
                {
                    if (type.GetTypeInfo().IsValueType)
                    {
                        _ilg.Ldloca(_objectLocal);
                        _ilg.InitObj(type);
                    }
                    else
                    {
                        _ilg.New(constructor);
                        _ilg.Stloc(_objectLocal);
                        _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, _objectLocal);
                    }
                }

                bool canReadSimpleDictionary = collectionContract.Kind == CollectionKind.Dictionary ||
                                               collectionContract.Kind == CollectionKind.GenericDictionary;
                if (canReadSimpleDictionary)
                {
                    _ilg.Load(_contextArg);
                    _ilg.LoadMember(JsonFormatGeneratorStatics.UseSimpleDictionaryFormatReadProperty);
                    _ilg.If();

                    ReadSimpleDictionary(collectionContract, itemType);

                    _ilg.Else();
                }

                LocalBuilder objectId = _ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead");
                _ilg.Call(_contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod);
                _ilg.Stloc(objectId);

                bool canReadPrimitiveArray = false;
                if (isArray && TryReadPrimitiveArray(itemType))
                {
                    canReadPrimitiveArray = true;
                    _ilg.IfNot();
                }

                LocalBuilder growingCollection = null;
                if (isArray)
                {
                    growingCollection = _ilg.DeclareLocal(type, "growingCollection");
                    _ilg.NewArray(itemType, 32);
                    _ilg.Stloc(growingCollection);
                }
                LocalBuilder i = _ilg.DeclareLocal(Globals.TypeOfInt, "i");
                object forLoop = _ilg.For(i, 0, Int32.MaxValue);
                // Empty namespace
                IsStartElement(_memberNamesArg, _emptyDictionaryStringArg);
                _ilg.If();
                _ilg.Call(_contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
                LocalBuilder value = ReadCollectionItem(collectionContract, itemType);
                if (isArray)
                {
                    MethodInfo ensureArraySizeMethod = XmlFormatGeneratorStatics.EnsureArraySizeMethod.MakeGenericMethod(itemType);
                    _ilg.Call(null, ensureArraySizeMethod, growingCollection, i);
                    _ilg.Stloc(growingCollection);
                    _ilg.StoreArrayElement(growingCollection, i, value);
                }
                else
                    StoreCollectionValue(_objectLocal, value, collectionContract);
                _ilg.Else();
                IsEndElement();
                _ilg.If();
                _ilg.Break(forLoop);
                _ilg.Else();
                HandleUnexpectedItemInCollection(i);
                _ilg.EndIf();
                _ilg.EndIf();

                _ilg.EndFor();
                if (isArray)
                {
                    MethodInfo trimArraySizeMethod = XmlFormatGeneratorStatics.TrimArraySizeMethod.MakeGenericMethod(itemType);
                    _ilg.Call(null, trimArraySizeMethod, growingCollection, i);
                    _ilg.Stloc(_objectLocal);
                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectWithIdMethod, objectId, _objectLocal);
                }

                if (canReadPrimitiveArray)
                {
                    _ilg.Else();
                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.AddNewObjectWithIdMethod, objectId, _objectLocal);
                    _ilg.EndIf();
                }

                if (canReadSimpleDictionary)
                {
                    _ilg.EndIf();
                }
            }
Esempio n. 38
0
 protected virtual bool ReflectionReadSpecialCollection(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, CollectionDataContract collectionContract, object resultCollection)
 {
     return(false);
 }
Esempio n. 39
0
 private LocalBuilder ReadCollectionItem(CollectionDataContract collectionContract, Type itemType)
 {
     if (collectionContract.Kind == CollectionKind.Dictionary || collectionContract.Kind == CollectionKind.GenericDictionary)
     {
         _ilg.Call(_contextArg, XmlFormatGeneratorStatics.ResetAttributesMethod);
         LocalBuilder value = _ilg.DeclareLocal(itemType, "valueRead");
         _ilg.Load(_collectionContractArg);
         _ilg.Call(JsonFormatGeneratorStatics.GetItemContractMethod);
         _ilg.Call(JsonFormatGeneratorStatics.GetRevisedItemContractMethod);
         _ilg.Load(_xmlReaderArg);
         _ilg.Load(_contextArg);
         _ilg.Call(JsonFormatGeneratorStatics.ReadJsonValueMethod);
         _ilg.ConvertValue(Globals.TypeOfObject, itemType);
         _ilg.Stloc(value);
         return value;
     }
     else
     {
         return ReadValue(itemType, JsonGlobals.itemString);
     }
 }
Esempio n. 40
0
 private object ReflectionInternalDeserialize(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, CollectionDataContract collectionContract, Type type, string name, string ns)
 {
     return(context.InternalDeserialize(xmlReader, DataContract.GetId(type.TypeHandle), type.TypeHandle, name, ns));
 }
			internal JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
			{
				return (XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContextComplexJson context, CollectionDataContract dataContract) => new JsonFormatWriterInterpreter (collectionContract).WriteCollectionToJson (xmlWriter, obj, context, dataContract);
			}
Esempio n. 42
0
 private bool IsArrayLikeCollection(CollectionDataContract collectionContract)
 {
     return(collectionContract.Kind == CollectionKind.Array || IsArrayLikeInterface(collectionContract));
 }
        public static IEnumerable ConvertGenericListToArray(DataContractJsonSerializer serializer, IEnumerable value, CollectionDataContract dataContract, XmlObjectSerializerWriteContextComplexJson context, bool writeServerType)
        {
            Type listArgumentType = dataContract.ItemType;

            if (listArgumentType.GetTypeInfo().IsGenericType)
            {
                listArgumentType = listArgumentType.GetGenericArguments()[0];
            }
            List <object> serializedList      = new List <object>();
            MethodInfo    getEnumeratorMethod = dataContract.GetEnumeratorMethod;

            IEnumerator enumerator = (getEnumeratorMethod == null) ? value.GetEnumerator() : (IEnumerator)getEnumeratorMethod.Invoke(value, Globals.EmptyTypeArray);

            while (enumerator.MoveNext())
            {
                if (enumerator.Current == null || enumerator.Current.GetType().GetTypeInfo().IsPrimitive)
                {
                    serializedList.Add(enumerator.Current);
                }
                else
                {
                    Type         currentItemType         = enumerator.Current.GetType();
                    DataContract currentItemDataContract = DataContract.GetDataContract(currentItemType);
                    bool         emitTypeInformation     = EmitTypeInformation(dataContract.ItemContract, currentItemType);
                    if (writeServerType || emitTypeInformation)
                    {
                        context.CheckIfTypeNeedsVerifcation(dataContract.ItemContract, currentItemDataContract);
                    }
                    context.PushKnownTypes(dataContract);
                    serializedList.Add(serializer.ConvertDataContractToObject(enumerator.Current, currentItemDataContract, context, (writeServerType || emitTypeInformation), dataContract.ItemType.TypeHandle));
                    context.PopKnownTypes(dataContract);
                }
            }
            return(serializedList);
        }
Esempio n. 44
0
        private CollectionSetItemDelegate GetCollectionSetItemDelegate <T>(CollectionDataContract collectionContract, object resultCollectionObject, bool isReadOnlyCollection)
        {
            if (isReadOnlyCollection && collectionContract.Kind == CollectionKind.Array)
            {
                int arraySize = ((Array)resultCollectionObject).Length;
                return((resultCollection, collectionItem, index) =>
                {
                    if (index == arraySize)
                    {
                        XmlObjectSerializerReadContext.ThrowArrayExceededSizeException(arraySize, collectionContract.UnderlyingType);
                    }

                    ((T[])resultCollection)[index] = (T)collectionItem;
                    return resultCollection;
                });
            }
            else if (!isReadOnlyCollection && IsArrayLikeCollection(collectionContract))
            {
                return((resultCollection, collectionItem, index) =>
                {
                    resultCollection = XmlObjectSerializerReadContext.EnsureArraySize((T[])resultCollection, index);
                    ((T[])resultCollection)[index] = (T)collectionItem;
                    return resultCollection;
                });
            }
            else if (collectionContract.Kind == CollectionKind.GenericDictionary || collectionContract.Kind == CollectionKind.Dictionary)
            {
                Type keyType   = collectionContract.ItemType.GenericTypeArguments[0];
                Type valueType = collectionContract.ItemType.GenericTypeArguments[1];
                Func <object, object> objectToKeyValuePairGetKey   = s_objectToKeyValuePairGetKey.MakeGenericMethod(keyType, valueType).CreateDelegate <Func <object, object> >();
                Func <object, object> objectToKeyValuePairGetValue = s_objectToKeyValuePairGetValue.MakeGenericMethod(keyType, valueType).CreateDelegate <Func <object, object> >();

                if (collectionContract.Kind == CollectionKind.GenericDictionary)
                {
                    return((resultCollection, collectionItem, index) =>
                    {
                        object key = objectToKeyValuePairGetKey(collectionItem);
                        object value = objectToKeyValuePairGetValue(collectionItem);

                        collectionContract.AddMethod.Invoke(resultCollection, new object[] { key, value });
                        return resultCollection;
                    });
                }
                else
                {
                    return((resultCollection, collectionItem, index) =>
                    {
                        object key = objectToKeyValuePairGetKey(collectionItem);
                        object value = objectToKeyValuePairGetValue(collectionItem);

                        IDictionary dict = (IDictionary)resultCollection;
                        dict.Add(key, value);
                        return resultCollection;
                    });
                }
            }
            else
            {
                Type collectionType        = resultCollectionObject.GetType();
                Type genericCollectionType = typeof(ICollection <T>);
                Type typeIList             = Globals.TypeOfIList;
                if (genericCollectionType.IsAssignableFrom(collectionType))
                {
                    return((resultCollection, collectionItem, index) =>
                    {
                        ((ICollection <T>)resultCollection).Add((T)collectionItem);
                        return resultCollection;
                    });
                }
                else if (typeIList.IsAssignableFrom(collectionType))
                {
                    return((resultCollection, collectionItem, index) =>
                    {
                        ((IList)resultCollection).Add(collectionItem);
                        return resultCollection;
                    });
                }
                else
                {
                    MethodInfo addMethod = collectionContract.AddMethod;
                    if (addMethod == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.CollectionMustHaveAddMethod, DataContract.GetClrTypeFullName(collectionContract.UnderlyingType))));
                    }

                    return((resultCollection, collectionItem, index) =>
                    {
                        addMethod.Invoke(resultCollection, new object[] { collectionItem });
                        return resultCollection;
                    });
                }
            }
        }
Esempio n. 45
0
        public void ReflectionWriteCollection(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContextComplexJson context, CollectionDataContract collectionContract)
        {
            JsonWriterDelegator jsonWriter = xmlWriter as JsonWriterDelegator;

            if (jsonWriter == null)
            {
                throw new ArgumentException(nameof(xmlWriter));
            }

            XmlDictionaryString itemName = context.CollectionItemName;

            if (collectionContract.Kind == CollectionKind.Array)
            {
                context.IncrementArrayCount(jsonWriter, (Array)obj);
                Type itemType = collectionContract.ItemType;
                if (!ReflectionTryWritePrimitiveArray(jsonWriter, obj, collectionContract.UnderlyingType, itemType, itemName))
                {
                    ReflectionWriteArrayAttribute(jsonWriter);

                    Array array = (Array)obj;
                    PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(itemType);
                    for (int i = 0; i < array.Length; ++i)
                    {
                        _reflectionClassWriter.ReflectionWriteStartElement(jsonWriter, itemName);
                        _reflectionClassWriter.ReflectionWriteValue(jsonWriter, context, itemType, array.GetValue(i), false, primitiveContract);
                        _reflectionClassWriter.ReflectionWriteEndElement(jsonWriter);
                    }
                }
            }
            else
            {
                collectionContract.IncrementCollectionCount(jsonWriter, obj, context);

                Type        enumeratorReturnType;
                IEnumerator enumerator = collectionContract.GetEnumeratorForCollection(obj, out enumeratorReturnType);

                bool canWriteSimpleDictionary = collectionContract.Kind == CollectionKind.GenericDictionary ||
                                                collectionContract.Kind == CollectionKind.Dictionary;

                bool useSimpleDictionaryFormat = context.UseSimpleDictionaryFormat;

                if (canWriteSimpleDictionary && useSimpleDictionaryFormat)
                {
                    ReflectionWriteObjectAttribute(jsonWriter);

                    while (enumerator.MoveNext())
                    {
                        object current = enumerator.Current;
                        object key     = ((IKeyValue)current).Key;
                        object value   = ((IKeyValue)current).Value;
                        _reflectionClassWriter.ReflectionWriteStartElement(jsonWriter, key.ToString());
                        _reflectionClassWriter.ReflectionWriteValue(jsonWriter, context, value.GetType(), value, false, primitiveContractForParamType: null);
                        _reflectionClassWriter.ReflectionWriteEndElement(jsonWriter);
                    }
                }
                else
                {
                    ReflectionWriteArrayAttribute(jsonWriter);

                    PrimitiveDataContract primitiveContractForType = PrimitiveDataContract.GetPrimitiveDataContract(enumeratorReturnType);
                    if (primitiveContractForType != null && primitiveContractForType.UnderlyingType != Globals.TypeOfObject)
                    {
                        while (enumerator.MoveNext())
                        {
                            object current = enumerator.Current;
                            context.IncrementItemCount(1);
                            primitiveContractForType.WriteXmlElement(jsonWriter, current, context, itemName, null /*namespace*/);
                        }
                    }
                    else
                    {
                        bool isDictionary = collectionContract.Kind == CollectionKind.Dictionary || collectionContract.Kind == CollectionKind.GenericDictionary;
                        while (enumerator.MoveNext())
                        {
                            object current = enumerator.Current;
                            context.IncrementItemCount(1);
                            _reflectionClassWriter.ReflectionWriteStartElement(jsonWriter, itemName);
                            if (isDictionary)
                            {
                                var itemContract     = XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract(collectionContract.ItemContract);
                                var jsonDataContract = JsonDataContract.GetJsonDataContract(itemContract);

                                jsonDataContract.WriteJsonValue(jsonWriter, current, context, collectionContract.ItemType.TypeHandle);
                            }
                            else
                            {
                                _reflectionClassWriter.ReflectionWriteValue(jsonWriter, context, enumeratorReturnType, current, false, primitiveContractForParamType: null);
                            }

                            _reflectionClassWriter.ReflectionWriteEndElement(jsonWriter);
                        }
                    }
                }
            }
        }
Esempio n. 46
0
        public void ReflectionReadGetOnlyCollection(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, XmlDictionaryString collectionItemName, XmlDictionaryString collectionItemNamespace, CollectionDataContract collectionContract)
        {
            object resultCollection = context.GetCollectionMember();

            if (ReflectionReadSpecialCollection(xmlReader, context, collectionContract, resultCollection))
            {
                return;
            }

            if (xmlReader.IsStartElement(collectionItemName, collectionItemNamespace))
            {
                if (resultCollection == null)
                {
                    XmlObjectSerializerReadContext.ThrowNullValueReturnedForGetOnlyCollectionException(collectionContract.UnderlyingType);
                }

                bool isReadOnlyCollection = true;
                resultCollection = ReadCollectionItems(xmlReader, context, collectionItemName, collectionItemNamespace, collectionContract, resultCollection, isReadOnlyCollection);
            }
        }
 public XmlFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
 {
     ilg = GenerateCollectionReaderHelper(collectionContract, false /*isGetOnlyCollection*/);
     ReadCollection(collectionContract);
     ilg.Load(objectLocal);
     ilg.ConvertValue(objectLocal.LocalType, ilg.CurrentMethod.ReturnType);
     return (XmlFormatCollectionReaderDelegate)ilg.EndMethod();
 }
Esempio n. 48
0
 public object ReflectionReadCollection(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, XmlDictionaryString collectionItemName, XmlDictionaryString collectionItemNamespace, CollectionDataContract collectionContract)
 {
     return(ReflectionReadCollectionCore(xmlReader, context, collectionItemName, collectionItemNamespace, collectionContract));
 }
 CodeGenerator GenerateCollectionReaderHelper(CollectionDataContract collectionContract, bool isGetOnlyCollection)
 {
     ilg = new CodeGenerator();
     bool memberAccessFlag = collectionContract.RequiresMemberAccessForRead(null);
     try
     {
         if (isGetOnlyCollection)
         {
             ilg.BeginMethod("Read" + collectionContract.StableName.Name + "FromXml" + "IsGetOnly", Globals.TypeOfXmlFormatGetOnlyCollectionReaderDelegate, memberAccessFlag);
         }
         else
         {
             ilg.BeginMethod("Read" + collectionContract.StableName.Name + "FromXml" + string.Empty, Globals.TypeOfXmlFormatCollectionReaderDelegate, memberAccessFlag);
         }
     }
     catch (SecurityException securityException)
     {
         if (memberAccessFlag && securityException.PermissionType.Equals(typeof(ReflectionPermission)))
         {
             collectionContract.RequiresMemberAccessForRead(securityException);
         }
         else
         {
             throw;
         }
     }
     InitArgs();
     DemandMemberAccessPermission(memberAccessFlag);
     collectionContractArg = ilg.GetArg(4);
     return ilg;
 }
Esempio n. 50
0
        private object ReflectionReadCollectionCore(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, XmlDictionaryString collectionItemName, XmlDictionaryString collectionItemNamespace, CollectionDataContract collectionContract)
        {
            bool isArray = (collectionContract.Kind == CollectionKind.Array);

            int    arraySize   = context.GetArraySize();
            object resultArray = null;

            if (isArray && ReflectionTryReadPrimitiveArray(xmlReader, context, collectionItemName, collectionItemNamespace, collectionContract.UnderlyingType, collectionContract.ItemType, arraySize, out resultArray))
            {
                return(resultArray);
            }

            object resultCollection = ReflectionCreateCollection(collectionContract);

            context.AddNewObject(resultCollection);
            context.IncrementItemCount(1);

            if (!ReflectionReadSpecialCollection(xmlReader, context, collectionContract, resultCollection))
            {
                bool isReadOnlyCollection = false;
                resultCollection = ReadCollectionItems(xmlReader, context, collectionItemName, collectionItemNamespace, collectionContract, resultCollection, isReadOnlyCollection);
            }

            return(resultCollection);
        }
            void ReadGetOnlyCollection(CollectionDataContract collectionContract)
            {
                Type type = collectionContract.UnderlyingType;
                Type itemType = collectionContract.ItemType;
                bool isArray = (collectionContract.Kind == CollectionKind.Array);
                string itemName = collectionContract.ItemName;
                string itemNs = collectionContract.StableName.Namespace;

                objectLocal = ilg.DeclareLocal(type, "objectDeserialized");
                ilg.Load(contextArg);
                ilg.LoadMember(XmlFormatGeneratorStatics.GetCollectionMemberMethod);
                ilg.ConvertValue(Globals.TypeOfObject, type);
                ilg.Stloc(objectLocal);

                //check that items are actually going to be deserialized into the collection
                IsStartElement(memberNamesArg, memberNamespacesArg);
                ilg.If();
                ilg.If(objectLocal, Cmp.EqualTo, null);
                ilg.Call(null, XmlFormatGeneratorStatics.ThrowNullValueReturnedForGetOnlyCollectionExceptionMethod, type);

                ilg.Else();
                LocalBuilder size = ilg.DeclareLocal(Globals.TypeOfInt, "arraySize");
                if (isArray)
                {
                    ilg.Load(objectLocal);
                    ilg.Call(XmlFormatGeneratorStatics.GetArrayLengthMethod);
                    ilg.Stloc(size);
                }

                ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal);

                LocalBuilder i = ilg.DeclareLocal(Globals.TypeOfInt, "i");
                object forLoop = ilg.For(i, 0, Int32.MaxValue);
                IsStartElement(memberNamesArg, memberNamespacesArg);
                ilg.If();
                ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
                LocalBuilder value = ReadCollectionItem(collectionContract, itemType, itemName, itemNs);
                if (isArray)
                {
                    ilg.If(size, Cmp.EqualTo, i);
                    ilg.Call(null, XmlFormatGeneratorStatics.ThrowArrayExceededSizeExceptionMethod, size, type);
                    ilg.Else();
                    ilg.StoreArrayElement(objectLocal, i, value);
                    ilg.EndIf();
                }
                else
                    StoreCollectionValue(objectLocal, value, collectionContract);
                ilg.Else();
                IsEndElement();
                ilg.If();
                ilg.Break(forLoop);
                ilg.Else();
                HandleUnexpectedItemInCollection(i);
                ilg.EndIf();
                ilg.EndIf();
                ilg.EndFor();
                ilg.Call(contextArg, XmlFormatGeneratorStatics.CheckEndOfArrayMethod, xmlReaderArg, size, memberNamesArg, memberNamespacesArg);

                ilg.EndIf();
                ilg.EndIf();
            }
Esempio n. 52
0
        private static void FindRefHandleCollectionDataContractMembers(object data, DataContract dataContract, ref Dictionary <DataContract, List <RefData> > alreadyRefdValues, ref Dictionary <DataContract, List <RefData> > nonRefdValues)
        {
            CollectionDataContract collectionContract = dataContract as CollectionDataContract;

            if (!collectionContract.IsDictionary)
            {
                foreach (object obj in (IEnumerable)data)
                {
                    if (obj != null)
                    {
                        FindAndAddRefd(obj, DataContract.GetDataContract(obj.GetType(), supportCollectionDataContract), ref alreadyRefdValues, ref nonRefdValues);
                    }
                }
            }
            else
            {
                IDictionary dictionary = data as IDictionary;
                if (dictionary != null)
                {
                    foreach (object key in dictionary.Keys)
                    {
                        if (key != null)
                        {
                            FindAndAddRefd(key, DataContract.GetDataContract(key.GetType(), supportCollectionDataContract), ref alreadyRefdValues, ref nonRefdValues);
                        }
                    }
                    foreach (object value in dictionary.Values)
                    {
                        if (value != null)
                        {
                            FindAndAddRefd(value, DataContract.GetDataContract(value.GetType(), supportCollectionDataContract), ref alreadyRefdValues, ref nonRefdValues);
                        }
                    }
                }
                else
                {
                    if (collectionContract.GetEnumeratorMethod != null)
                    {
                        object dictEnumObj = null;
                        try
                        {
                            dictEnumObj = collectionContract.GetEnumeratorMethod.Invoke(data, new object[] { });
                        }
                        catch (Exception) { }
                        IDictionaryEnumerator dictEnum = dictEnumObj as IDictionaryEnumerator;
                        if (dictEnum != null)
                        {
                            while (dictEnum.MoveNext())
                            {
                                FindAndAddRefd(dictEnum.Key, DataContract.GetDataContract(dictEnum.Key.GetType(), supportCollectionDataContract), ref alreadyRefdValues, ref nonRefdValues);
                            }
                            dictEnum.Reset();
                            while (dictEnum.MoveNext())
                            {
                                if (dictEnum.Value != null)
                                {
                                    FindAndAddRefd(dictEnum.Value, DataContract.GetDataContract(dictEnum.Value.GetType(), supportCollectionDataContract), ref alreadyRefdValues, ref nonRefdValues);
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new Exception("TestDriver Exception: Dictionary CollectionDataCotnract Type Not Supported");
                    }
                }
            }
        }
        //Deserialize '[...]' json string. The contents of the list can also be a dictionary i.e. [{...}]. The content type is detected
        //based on the type of CollectionDataContract.ItemContract.
        public static object ConvertICollectionToCollectionDataContract(DataContractJsonSerializer serializer, CollectionDataContract contract, object deserializedValue, XmlObjectSerializerReadContextComplexJson context)
        {
            Dictionary <string, object> valueAsDictionary = deserializedValue as Dictionary <string, object>;

            //Check to see if the dictionary (if it is a dictionary)is a regular Dictionary i.e { Key="key"; Value="value} and doesnt contain the __type string
            //for ex. the dictionary { __type="XXX"; Key="key"; Value="value} needs to be parsed as ClassDataContract
            if (valueAsDictionary != null && (!valueAsDictionary.ContainsKey(JsonGlobals.KeyString) || valueAsDictionary.ContainsKey(JsonGlobals.ServerTypeString)))
            {
                //If not then its a dictionary for either of these cases
                //1. Empty object - {}
                //2. Containes the __type information
                //3. Is a DateTimeOffsetDictionary
                return(ConvertDictionary(serializer, contract, valueAsDictionary, context));
            }

            object returnValue = (contract.Constructor != null) ? contract.Constructor.Invoke(Array.Empty <Type>()) : null;

            bool       isCollectionDataContractDictionary = contract.IsDictionary;
            MethodInfo addMethod      = contract.AddMethod;
            bool       convertToArray = contract.Kind == CollectionKind.Array;

            if (contract.UnderlyingType.GetTypeInfo().IsInterface || returnValue == null)
            {
                switch (contract.Kind)
                {
                case CollectionKind.Collection:
                case CollectionKind.GenericCollection:
                case CollectionKind.Enumerable:
                case CollectionKind.GenericEnumerable:
                case CollectionKind.List:
                case CollectionKind.GenericList:
                case CollectionKind.Array:
                    if (contract.UnderlyingType.GetTypeInfo().IsValueType)
                    {
                        //Initialize struct
                        returnValue = XmlFormatReaderGenerator.TryGetUninitializedObjectWithFormatterServices(contract.UnderlyingType);
                    }
                    else
                    {
                        returnValue    = Activator.CreateInstance(Globals.TypeOfListGeneric.MakeGenericType(contract.ItemType));
                        convertToArray = true;
                    }
                    break;

                case CollectionKind.GenericDictionary:
                    returnValue = Activator.CreateInstance(Globals.TypeOfDictionaryGeneric.MakeGenericType(contract.ItemType.GetGenericArguments()));
                    break;

                case CollectionKind.Dictionary:
                    returnValue = Activator.CreateInstance(Globals.TypeOfDictionaryGeneric.MakeGenericType(Globals.TypeOfObject, Globals.TypeOfObject));
                    break;
                }
            }
            if (addMethod == null)
            {
                //addMethod is null for IDictionary, IList and array types.
                Type[] paramArray = (contract.ItemType.GetTypeInfo().IsGenericType&& !convertToArray) ? contract.ItemType.GetGenericArguments() : new Type[] { contract.ItemType };
                addMethod = returnValue.GetType().GetMethod(Globals.AddMethodName, paramArray);
            }

            IEnumerator enumerator  = ((ICollection)deserializedValue).GetEnumerator();
            object      currentItem = null;

            object[] currentItemArray = null;
            while (enumerator.MoveNext())
            {
                DataContract itemContract = contract.ItemContract;
                if (itemContract is ClassDataContract)
                {
                    itemContract = XmlObjectSerializerWriteContextComplexJson.GetRevisedItemContract(itemContract);
                }
                currentItem      = serializer.ConvertObjectToDataContract(itemContract, enumerator.Current, context);
                currentItemArray = new object[] { currentItem };
                if (isCollectionDataContractDictionary)
                {
                    Type       currentItemType = currentItem.GetType();
                    MemberInfo keyMember       = currentItemType.GetMember("Key")[0];
                    MemberInfo valueMember     = currentItemType.GetMember("Value")[0];
                    currentItemArray = new object[] { DataContractToObjectConverter.GetMemberValue(currentItem, keyMember, currentItemType), DataContractToObjectConverter.GetMemberValue(currentItem, valueMember, currentItemType) };
                }
                addMethod.Invoke(returnValue, currentItemArray);
            }

            return((convertToArray) ? ConvertToArray(contract.ItemType, (ICollection)returnValue) : returnValue);
        }
            private void WriteCollection(CollectionDataContract collectionContract)
            {
                LocalBuilder itemNamespace = _ilg.DeclareLocal(typeof(XmlDictionaryString), "itemNamespace");

                _ilg.Load(_dataContractArg);
                _ilg.LoadMember(XmlFormatGeneratorStatics.NamespaceProperty);
                _ilg.Store(itemNamespace);

                LocalBuilder itemName = _ilg.DeclareLocal(typeof(XmlDictionaryString), "itemName");

                _ilg.Load(_dataContractArg);
                _ilg.LoadMember(XmlFormatGeneratorStatics.CollectionItemNameProperty);
                _ilg.Store(itemName);

                if (collectionContract.ChildElementNamespace != null)
                {
                    _ilg.Load(_xmlWriterArg);
                    _ilg.Load(_dataContractArg);
                    _ilg.LoadMember(XmlFormatGeneratorStatics.ChildElementNamespaceProperty);
                    _ilg.Call(XmlFormatGeneratorStatics.WriteNamespaceDeclMethod);
                }

                if (collectionContract.Kind == CollectionKind.Array)
                {
                    Type         itemType = collectionContract.ItemType;
                    LocalBuilder i        = _ilg.DeclareLocal(Globals.TypeOfInt, "i");

                    _ilg.Call(_contextArg, XmlFormatGeneratorStatics.IncrementArrayCountMethod, _xmlWriterArg, _objectLocal);

                    if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, _objectLocal, itemName, itemNamespace))
                    {
                        _ilg.For(i, 0, _objectLocal);
                        if (!TryWritePrimitive(itemType, null /*value*/, null /*memberInfo*/, i /*arrayItemIndex*/, itemNamespace, itemName, 0 /*nameIndex*/))
                        {
                            WriteStartElement(itemType, collectionContract.Namespace, itemNamespace, itemName, 0 /*nameIndex*/);
                            _ilg.LoadArrayElement(_objectLocal, i);
                            LocalBuilder memberValue = _ilg.DeclareLocal(itemType, "memberValue");
                            _ilg.Stloc(memberValue);
                            WriteValue(memberValue, false /*writeXsiType*/);
                            WriteEndElement();
                        }
                        _ilg.EndFor();
                    }
                }
                else
                {
                    MethodInfo incrementCollectionCountMethod = null;
                    switch (collectionContract.Kind)
                    {
                    case CollectionKind.Collection:
                    case CollectionKind.List:
                    case CollectionKind.Dictionary:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
                        break;

                    case CollectionKind.GenericCollection:
                    case CollectionKind.GenericList:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
                        break;

                    case CollectionKind.GenericDictionary:
                        incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
                        break;
                    }
                    if (incrementCollectionCountMethod != null)
                    {
                        _ilg.Call(_contextArg, incrementCollectionCountMethod, _xmlWriterArg, _objectLocal);
                    }

                    bool   isDictionary = false, isGenericDictionary = false;
                    Type   enumeratorType = null;
                    Type[] keyValueTypes  = null;
                    if (collectionContract.Kind == CollectionKind.GenericDictionary)
                    {
                        isGenericDictionary = true;
                        keyValueTypes       = collectionContract.ItemType.GetGenericArguments();
                        enumeratorType      = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
                    }
                    else if (collectionContract.Kind == CollectionKind.Dictionary)
                    {
                        isDictionary   = true;
                        keyValueTypes  = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
                        enumeratorType = Globals.TypeOfDictionaryEnumerator;
                    }
                    else
                    {
                        enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
                    }
                    MethodInfo moveNextMethod   = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, Globals.EmptyTypeArray);
                    MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, Globals.EmptyTypeArray);
                    if (moveNextMethod == null || getCurrentMethod == null)
                    {
                        if (enumeratorType.GetTypeInfo().IsInterface)
                        {
                            if (moveNextMethod == null)
                            {
                                moveNextMethod = XmlFormatGeneratorStatics.MoveNextMethod;
                            }
                            if (getCurrentMethod == null)
                            {
                                getCurrentMethod = XmlFormatGeneratorStatics.GetCurrentMethod;
                            }
                        }
                        else
                        {
                            Type           ienumeratorInterface = Globals.TypeOfIEnumerator;
                            CollectionKind kind = collectionContract.Kind;
                            if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
                            {
                                Type[] interfaceTypes = enumeratorType.GetInterfaces();
                                foreach (Type interfaceType in interfaceTypes)
                                {
                                    if (interfaceType.GetTypeInfo().IsGenericType &&
                                        interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric &&
                                        interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
                                    {
                                        ienumeratorInterface = interfaceType;
                                        break;
                                    }
                                }
                            }
                            if (moveNextMethod == null)
                            {
                                moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
                            }
                            if (getCurrentMethod == null)
                            {
                                getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
                            }
                        }
                    }
                    Type         elementType  = getCurrentMethod.ReturnType;
                    LocalBuilder currentValue = _ilg.DeclareLocal(elementType, "currentValue");

                    LocalBuilder enumerator = _ilg.DeclareLocal(enumeratorType, "enumerator");
                    _ilg.Call(_objectLocal, collectionContract.GetEnumeratorMethod);
                    if (isDictionary)
                    {
                        _ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, Globals.TypeOfIDictionaryEnumerator);
                        _ilg.New(XmlFormatGeneratorStatics.DictionaryEnumeratorCtor);
                    }
                    else if (isGenericDictionary)
                    {
                        Type            ctorParam    = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
                        ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, new Type[] { ctorParam });
                        _ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, ctorParam);
                        _ilg.New(dictEnumCtor);
                    }
                    _ilg.Stloc(enumerator);

                    _ilg.ForEach(currentValue, elementType, enumeratorType, enumerator, getCurrentMethod);
                    if (incrementCollectionCountMethod == null)
                    {
                        _ilg.Call(_contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
                    }
                    if (!TryWritePrimitive(elementType, currentValue, null /*memberInfo*/, null /*arrayItemIndex*/, itemNamespace, itemName, 0 /*nameIndex*/))
                    {
                        WriteStartElement(elementType, collectionContract.Namespace, itemNamespace, itemName, 0 /*nameIndex*/);

                        if (isGenericDictionary || isDictionary)
                        {
                            _ilg.Call(_dataContractArg, XmlFormatGeneratorStatics.GetItemContractMethod);
                            _ilg.Load(_xmlWriterArg);
                            _ilg.Load(currentValue);
                            _ilg.ConvertValue(currentValue.LocalType, Globals.TypeOfObject);
                            _ilg.Load(_contextArg);
                            _ilg.Call(XmlFormatGeneratorStatics.WriteXmlValueMethod);
                        }
                        else
                        {
                            WriteValue(currentValue, false /*writeXsiType*/);
                        }
                        WriteEndElement();
                    }
                    _ilg.EndForEach(moveNextMethod);
                }
            }
 internal JsonFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
 {
     return _helper.GenerateCollectionWriter(collectionContract);
 }
        public static List <object> ConvertGenericDictionaryToArray(DataContractJsonSerializer serializer, IEnumerable value, CollectionDataContract dataContract, XmlObjectSerializerWriteContextComplexJson context, bool writeServerType)
        {
            List <object> keyValuePair = new List <object>();
            Dictionary <string, object> currentEntry;

            Type[]     declaredTypes       = dataContract.ItemType.GetGenericArguments();
            MethodInfo getEnumeratorMethod = dataContract.GetEnumeratorMethod;

            IDictionaryEnumerator enumerator = (IDictionaryEnumerator)((getEnumeratorMethod == null) ? value.GetEnumerator() : (IDictionaryEnumerator)getEnumeratorMethod.Invoke(value, Globals.EmptyTypeArray));

            while (enumerator.MoveNext())
            {
                DictionaryEntry current             = enumerator.Entry;
                DataContract    currentDataContract = DataContract.GetDataContract(enumerator.Current.GetType());
                currentEntry = new Dictionary <string, object>();
                if (writeServerType)
                {
                    AddTypeInformation(currentEntry, currentDataContract);
                }
                context.PushKnownTypes(dataContract);
                AddDictionaryEntryData(serializer, currentEntry, writeServerType ? JsonGlobals.KeyString.ToLowerInvariant() : JsonGlobals.KeyString, declaredTypes[0], current.Key, context);
                AddDictionaryEntryData(serializer, currentEntry, writeServerType ? JsonGlobals.ValueString.ToLowerInvariant() : JsonGlobals.ValueString, declaredTypes[1], current.Value, context);
                keyValuePair.Add(currentEntry);
                context.PopKnownTypes(dataContract);
            }
            return(keyValuePair);
        }
 void ThrowIfCannotSerializeReadOnlyTypes(CollectionDataContract classContract)
 {
     ThrowIfCannotSerializeReadOnlyTypes(XmlFormatGeneratorStatics.CollectionSerializationExceptionMessageProperty);
 }
 public XmlFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
 {
     return _helper.GenerateCollectionReader(collectionContract);
 }
Esempio n. 59
0
            private void StoreCollectionValue(LocalBuilder collection, LocalBuilder value, CollectionDataContract collectionContract)
            {
                if (collectionContract.Kind == CollectionKind.GenericDictionary || collectionContract.Kind == CollectionKind.Dictionary)
                {
                    ClassDataContract keyValuePairContract = DataContract.GetDataContract(value.LocalType) as ClassDataContract;
                    if (keyValuePairContract == null)
                    {
                        DiagnosticUtility.DebugAssert("Failed to create contract for KeyValuePair type");
                    }
                    DataMember   keyMember   = keyValuePairContract.Members[0];
                    DataMember   valueMember = keyValuePairContract.Members[1];
                    LocalBuilder pairKey     = _ilg.DeclareLocal(keyMember.MemberType, keyMember.Name);
                    LocalBuilder pairValue   = _ilg.DeclareLocal(valueMember.MemberType, valueMember.Name);
                    _ilg.LoadAddress(value);
                    _ilg.LoadMember(keyMember.MemberInfo);
                    _ilg.Stloc(pairKey);
                    _ilg.LoadAddress(value);
                    _ilg.LoadMember(valueMember.MemberInfo);
                    _ilg.Stloc(pairValue);

                    _ilg.Call(collection, collectionContract.AddMethod, pairKey, pairValue);
                    if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid)
                    {
                        _ilg.Pop();
                    }
                }
                else
                {
                    _ilg.Call(collection, collectionContract.AddMethod, value);
                    if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid)
                    {
                        _ilg.Pop();
                    }
                }
            }
Esempio n. 60
0
 internal XmlFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
 {
     return(_helper.GenerateCollectionWriter(collectionContract));
 }