object PopulateList( IList list, BitStreamReader reader, ArrayContract contract, DsdlProperty containerProperty, ArrayDsdlType scheme, bool tailArrayOptimization) { object underlyingList = list is IWrappedCollection wrappedCollection ? wrappedCollection.UnderlyingCollection : list; if (contract.ItemContract == null) { contract.ItemContract = GetContractSafe(contract.CollectionItemType); } object ReadArrayItem(bool tao = false) { return(CreateValueInternal(reader, contract.ItemContract, null, contract, containerProperty, null, scheme.ElementType, contract.CollectionItemType, tao)); } switch (scheme.Mode) { case ArrayDsdlTypeMode.Static: { for (int i = 0; i < scheme.MaxSize; i++) { list.Add(ReadArrayItem()); } break; } case ArrayDsdlTypeMode.Dynamic: { if (tailArrayOptimization && scheme.ElementType.MinBitlen >= 8) { while (reader.LengthInBytes - reader.CurrentIndex > 1) { list.Add(ReadArrayItem()); } } else { var arraySize = ReadDynamicArraySize(reader, scheme); for (int i = 0; i < arraySize; i++) { var tao = i == arraySize - 1 ? tailArrayOptimization : false; list.Add(ReadArrayItem(tao)); } } break; } default: throw new ArgumentOutOfRangeException(nameof(ArrayDsdlTypeMode)); } return(underlyingList); }
IList CreateNewList(BitStreamReader reader, ArrayContract contract, out bool createdFromNonDefaultCreator) { // some types like non-generic IEnumerable can be serialized but not deserialized if (!contract.CanDeserialize) { throw new SerializationException("Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType)); } if (contract.OverrideCreator != null) { if (contract.HasParameterizedCreator) { createdFromNonDefaultCreator = true; return(contract.CreateTemporaryCollection()); } else { object list = contract.OverrideCreator(); if (contract.ShouldCreateWrapper) { list = contract.CreateWrapper(list); } createdFromNonDefaultCreator = false; return((IList)list); } } else if (contract.IsReadOnlyOrFixedSize) { createdFromNonDefaultCreator = true; IList list = contract.CreateTemporaryCollection(); if (contract.ShouldCreateWrapper) { list = contract.CreateWrapper(list); } return(list); } else if (contract.DefaultCreator != null && !contract.DefaultCreatorNonPublic) { object list = contract.DefaultCreator(); if (contract.ShouldCreateWrapper) { list = contract.CreateWrapper(list); } createdFromNonDefaultCreator = false; return((IList)list); } else if (contract.HasParameterizedCreatorInternal) { createdFromNonDefaultCreator = true; return(contract.CreateTemporaryCollection()); } else { if (!contract.IsInstantiable) { throw new SerializationException("Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); } throw new SerializationException("Unable to find a constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); } }