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); }
IEnumerable ReadStaticArray(BitStreamReader reader, ArrayDsdlType t) { var result = new object[t.MaxSize]; for (int i = 0; i < t.MaxSize; i++) { result[i] = CreateUnknownObject(reader, t.ElementType); } return(result); }
static void PrintArray(object obj, StringBuilder sb, int tabs, ArrayDsdlType t) { var enumerable = obj as IEnumerable; if (enumerable == null) { throw new ArgumentException("Cannot cast object to enumerable.", nameof(obj)); } var arrayType = t.ElementType; var isSLType = IsSingleLineType(arrayType); sb.Append("["); if (!isSLType) { sb.AppendLine(); } bool isFirst = true; foreach (var i in enumerable) { if (!isFirst) { sb.Append(", "); if (!isSLType) { sb.AppendLine(); Tab(sb, tabs); } } isFirst = false; Print(i, sb, tabs + 1, arrayType); } if (!isSLType) { Tab(sb, tabs - 1); } sb.Append("]"); }
IEnumerable ReadDynamicArray(BitStreamReader reader, ArrayDsdlType t, bool tailArrayOptimization) { if (tailArrayOptimization && t.ElementType.MinBitlen >= 8) { var result = new ArrayList(); while (reader.LengthInBytes - reader.CurrentIndex > 1) { result.Add(CreateUnknownObject(reader, t.ElementType)); } return(result); } else { var arraySize = ReadDynamicArraySize(reader, t); var result = new object[arraySize]; for (int i = 0; i < arraySize; i++) { var tao = i == arraySize - 1 ? tailArrayOptimization : false; result[i] = CreateUnknownObject(reader, t.ElementType, tao); } return(result); } }
object CreateList( BitStreamReader reader, IContract contract, DsdlProperty member, object existingValue, ArrayDsdlType scheme, bool tailArrayOptimization) { if (HasNoDefinedType(contract)) { return(CreateUnknownObject(reader, scheme, tailArrayOptimization)); } if (!(contract is ArrayContract arrayContract)) { throw new SerializationException("Could not resolve type to IContract."); } if (existingValue == null) { var list = CreateNewList(reader, arrayContract, out bool createdFromNonDefaultCreator); if (createdFromNonDefaultCreator && !arrayContract.HasParameterizedCreatorInternal && !arrayContract.IsArray) { throw new SerializationException($"Cannot deserialize readonly or fixed size list: {contract.UnderlyingType}."); } if (arrayContract.IsMultidimensionalArray) { throw new NotSupportedException("Multidimensional arrays are not supported."); } PopulateList(list, reader, arrayContract, member, scheme, tailArrayOptimization); if (createdFromNonDefaultCreator) { if (arrayContract.IsArray) { Array a = Array.CreateInstance(arrayContract.CollectionItemType, list.Count); list.CopyTo(a, 0); list = a; } else { ObjectConstructor <object> creator = arrayContract.OverrideCreator ?? arrayContract.ParameterizedCreator; return(creator(list)); } } else if (list is IWrappedCollection wrappedCollection) { return(wrappedCollection.UnderlyingCollection); } return(list); } else { if (!arrayContract.CanDeserialize) { throw new SerializationException($"Cannot populate list type {contract.CreatedType}."); } return(PopulateList( (arrayContract.ShouldCreateWrapper || !(existingValue is IList list)) ? arrayContract.CreateWrapper(existingValue) : list, reader, arrayContract, member, scheme, tailArrayOptimization)); } }
int ReadDynamicArraySize(BitStreamReader reader, ArrayDsdlType t) { var bitLen = BitSerializer.IntBitLength(t.MaxSize + 1); return((int)BitSerializer.ReadUInt(reader, bitLen)); }
void WriteDynamicArraySize(BitStreamWriter writer, int count, ArrayDsdlType arrayDsdlType) { var bitLen = BitSerializer.IntBitLength(arrayDsdlType.MaxSize + 1); BitSerializer.Write(writer, count, bitLen); }