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 = context.GetCollectionMember();

            //check that items are actually going to be deserialized into the collection
            if (IsStartElement(this.itemName, this.itemNamespace))
            {
                if (objectLocal == null)
                {
                    XmlObjectSerializerReadContext.ThrowNullValueReturnedForGetOnlyCollectionException(type);
                }
                else
                {
                    int size = 0;
                    if (isArray)
                    {
                        size = ((Array)objectLocal).Length;
                    }
                    context.AddNewObject(objectLocal);
                    for (int i = 0; i < int.MaxValue;)
                    {
                        if (IsStartElement(this.itemName, this.itemNamespace))
                        {
                            context.IncrementItemCount(1);
                            var value = ReadCollectionItem(collectionContract, itemType, itemName, itemNs);
                            if (isArray)
                            {
                                if (size == i)
                                {
                                    XmlObjectSerializerReadContext.ThrowArrayExceededSizeException(size, type);
                                }
                                else
                                {
                                    ((Array)objectLocal).SetValue(value, i);
                                }
                            }
                            else
                            {
                                StoreCollectionValue(objectLocal, itemType, value, collectionContract);
                            }
                        }
                        else if (IsEndElement())
                        {
                            break;
                        }
                        else
                        {
                            HandleUnexpectedItemInCollection(ref i);
                        }
                    }
                    context.CheckEndOfArray(xmlReader, size, this.itemName, this.itemNamespace);
                }
            }
        }
Beispiel #2
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   = (Func <object, object>)s_objectToKeyValuePairGetKey.MakeGenericMethod(keyType, valueType).CreateDelegate(typeof(Func <object, object>));
                Func <object, object> objectToKeyValuePairGetValue = (Func <object, object>)s_objectToKeyValuePairGetValue.MakeGenericMethod(keyType, valueType).CreateDelegate(typeof(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;
                    });
                }
            }
        }