System.Runtime.Serialization.XmlFormatReaderGenerator.XmlFormatReaderGenerator.CriticalHelper.ReadCollection C# (CSharp) Method

ReadCollection() private method

private ReadCollection ( CollectionDataContract collectionContract ) : void
collectionContract CollectionDataContract
return void
            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, Array.Empty<Type>());
                            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.GetTypeInfo().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();
                }
            }