internal bool TryDeserializeAuxiliaryType(ProtoReader reader, DataFormat format, int tag, Type type, ref object value, bool skipOtherFields, bool asListItem, bool autoCreate, bool insideList) { if (type == null) { throw new ArgumentNullException("type"); } ProtoTypeCode typecode = Helpers.GetTypeCode(type); int modelKey; WireType wiretype = this.GetWireType(typecode, format, ref type, out modelKey); bool found = false; if (wiretype == WireType.None) { Type itemType = TypeModel.GetListItemType(this, type); if (itemType == null && type.IsArray && type.GetArrayRank() == 1 && type != typeof(byte[])) { itemType = type.GetElementType(); } if (itemType != null) { if (insideList) { throw TypeModel.CreateNestedListsNotSupported(); } found = this.TryDeserializeList(this, reader, format, tag, type, itemType, ref value); if (!found && autoCreate) { value = TypeModel.CreateListInstance(type, itemType); } return(found); } else { TypeModel.ThrowUnexpectedType(type); } } while (!found || !asListItem) { int fieldNumber = reader.ReadFieldHeader(); if (fieldNumber <= 0) { break; } if (fieldNumber != tag) { if (!skipOtherFields) { throw ProtoReader.AddErrorData(new InvalidOperationException("Expected field " + tag.ToString() + ", but found " + fieldNumber.ToString()), reader); } reader.SkipField(); } else { found = true; reader.Hint(wiretype); if (modelKey >= 0) { switch (wiretype) { case WireType.String: case WireType.StartGroup: { SubItemToken token = ProtoReader.StartSubItem(reader); value = this.Deserialize(modelKey, value, reader); ProtoReader.EndSubItem(token, reader); break; } default: value = this.Deserialize(modelKey, value, reader); break; } } else { ProtoTypeCode protoTypeCode = typecode; switch (protoTypeCode) { case ProtoTypeCode.Boolean: value = reader.ReadBoolean(); break; case ProtoTypeCode.Char: value = (char)reader.ReadUInt16(); break; case ProtoTypeCode.SByte: value = reader.ReadSByte(); break; case ProtoTypeCode.Byte: value = reader.ReadByte(); break; case ProtoTypeCode.Int16: value = reader.ReadInt16(); break; case ProtoTypeCode.UInt16: value = reader.ReadUInt16(); break; case ProtoTypeCode.Int32: value = reader.ReadInt32(); break; case ProtoTypeCode.UInt32: value = reader.ReadUInt32(); break; case ProtoTypeCode.Int64: value = reader.ReadInt64(); break; case ProtoTypeCode.UInt64: value = reader.ReadUInt64(); break; case ProtoTypeCode.Single: value = reader.ReadSingle(); break; case ProtoTypeCode.Double: value = reader.ReadDouble(); break; case ProtoTypeCode.Decimal: value = BclHelpers.ReadDecimal(reader); break; case ProtoTypeCode.DateTime: value = BclHelpers.ReadDateTime(reader); break; case (ProtoTypeCode)17: break; case ProtoTypeCode.String: value = reader.ReadString(); break; default: switch (protoTypeCode) { case ProtoTypeCode.TimeSpan: value = BclHelpers.ReadTimeSpan(reader); break; case ProtoTypeCode.ByteArray: value = ProtoReader.AppendBytes((byte[])value, reader); break; case ProtoTypeCode.Guid: value = BclHelpers.ReadGuid(reader); break; case ProtoTypeCode.Uri: value = new Uri(reader.ReadString()); break; } break; } } } } if (!found && !asListItem && autoCreate && type != typeof(string)) { value = Activator.CreateInstance(type); } return(found); }
private bool TryDeserializeList(TypeModel model, ProtoReader reader, DataFormat format, int tag, Type listType, Type itemType, ref object value) { bool isList; MethodInfo addMethod = TypeModel.ResolveListAdd(model, listType, itemType, out isList); if (addMethod == null) { throw new NotSupportedException("Unknown list variant: " + listType.FullName); } bool found = false; object nextItem = null; IList list = value as IList; object[] args = isList ? null : new object[1]; BasicList arraySurrogate = listType.IsArray ? new BasicList() : null; while (this.TryDeserializeAuxiliaryType(reader, format, tag, itemType, ref nextItem, true, true, true, true)) { found = true; if (value == null && arraySurrogate == null) { value = TypeModel.CreateListInstance(listType, itemType); list = (value as IList); } if (list != null) { list.Add(nextItem); } else { if (arraySurrogate != null) { arraySurrogate.Add(nextItem); } else { args[0] = nextItem; addMethod.Invoke(value, args); } } nextItem = null; } if (arraySurrogate != null) { if (value != null) { if (arraySurrogate.Count != 0) { Array existing = (Array)value; Array newArray = Array.CreateInstance(itemType, existing.Length + arraySurrogate.Count); Array.Copy(existing, newArray, existing.Length); arraySurrogate.CopyTo(newArray, existing.Length); value = newArray; } } else { Array newArray = Array.CreateInstance(itemType, arraySurrogate.Count); arraySurrogate.CopyTo(newArray, 0); value = newArray; } } return(found); }