internal bool TrySerializeAuxiliaryType(ProtoWriter writer, Type type, DataFormat format, int tag, object value, bool isInsideList) { if (type == null) { type = value.GetType(); } ProtoTypeCode typecode = Helpers.GetTypeCode(type); int modelKey; WireType wireType = this.GetWireType(typecode, format, ref type, out modelKey); if (modelKey >= 0) { if (Helpers.IsEnum(type)) { this.Serialize(modelKey, value, writer); return(true); } ProtoWriter.WriteFieldHeader(tag, wireType, writer); switch (wireType) { case WireType.None: throw ProtoWriter.CreateException(writer); case WireType.String: case WireType.StartGroup: { SubItemToken token = ProtoWriter.StartSubItem(value, writer); this.Serialize(modelKey, value, writer); ProtoWriter.EndSubItem(token, writer); return(true); } } this.Serialize(modelKey, value, writer); return(true); } else { if (wireType != WireType.None) { ProtoWriter.WriteFieldHeader(tag, wireType, writer); } ProtoTypeCode protoTypeCode = typecode; switch (protoTypeCode) { case ProtoTypeCode.Boolean: ProtoWriter.WriteBoolean((bool)value, writer); return(true); case ProtoTypeCode.Char: ProtoWriter.WriteUInt16((ushort)((char)value), writer); return(true); case ProtoTypeCode.SByte: ProtoWriter.WriteSByte((sbyte)value, writer); return(true); case ProtoTypeCode.Byte: ProtoWriter.WriteByte((byte)value, writer); return(true); case ProtoTypeCode.Int16: ProtoWriter.WriteInt16((short)value, writer); return(true); case ProtoTypeCode.UInt16: ProtoWriter.WriteUInt16((ushort)value, writer); return(true); case ProtoTypeCode.Int32: ProtoWriter.WriteInt32((int)value, writer); return(true); case ProtoTypeCode.UInt32: ProtoWriter.WriteUInt32((uint)value, writer); return(true); case ProtoTypeCode.Int64: ProtoWriter.WriteInt64((long)value, writer); return(true); case ProtoTypeCode.UInt64: ProtoWriter.WriteUInt64((ulong)value, writer); return(true); case ProtoTypeCode.Single: ProtoWriter.WriteSingle((float)value, writer); return(true); case ProtoTypeCode.Double: ProtoWriter.WriteDouble((double)value, writer); return(true); case ProtoTypeCode.Decimal: BclHelpers.WriteDecimal((decimal)value, writer); return(true); case ProtoTypeCode.DateTime: BclHelpers.WriteDateTime((DateTime)value, writer); return(true); case (ProtoTypeCode)17: break; case ProtoTypeCode.String: ProtoWriter.WriteString((string)value, writer); return(true); default: switch (protoTypeCode) { case ProtoTypeCode.TimeSpan: BclHelpers.WriteTimeSpan((TimeSpan)value, writer); return(true); case ProtoTypeCode.ByteArray: ProtoWriter.WriteBytes((byte[])value, writer); return(true); case ProtoTypeCode.Guid: BclHelpers.WriteGuid((Guid)value, writer); return(true); case ProtoTypeCode.Uri: ProtoWriter.WriteString(((Uri)value).AbsoluteUri, writer); return(true); } break; } IEnumerable sequence = value as IEnumerable; if (sequence == null) { return(false); } if (isInsideList) { throw TypeModel.CreateNestedListsNotSupported(); } foreach (object item in sequence) { if (item == null) { throw new NullReferenceException(); } if (!this.TrySerializeAuxiliaryType(writer, null, format, tag, item, true)) { TypeModel.ThrowUnexpectedType(item.GetType()); } } return(true); } }
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); }
internal void ResolveListTypes(Type type, ref Type itemType, ref Type defaultType) { if (type == null) { return; } if (Helpers.GetTypeCode(type) != ProtoTypeCode.Unknown) { return; } if (this[type].IgnoreListHandling) { return; } if (type.IsArray) { if (type.GetArrayRank() != 1) { throw new NotSupportedException("Multi-dimension arrays are supported"); } itemType = type.GetElementType(); if (itemType == base.MapType(typeof(byte))) { Type type2; itemType = (type2 = null); defaultType = type2; } else { defaultType = type; } } if (itemType == null) { itemType = TypeModel.GetListItemType(this, type); } if (itemType != null) { Type nestedItemType = null; Type nestedDefaultType = null; this.ResolveListTypes(itemType, ref nestedItemType, ref nestedDefaultType); if (nestedItemType != null) { throw TypeModel.CreateNestedListsNotSupported(); } } if (itemType != null && defaultType == null) { if (type.IsClass && !type.IsAbstract && Helpers.GetConstructor(type, Helpers.EmptyTypes, true) != null) { defaultType = type; } if (defaultType == null && type.IsInterface) { Type[] genArgs; if (type.IsGenericType && type.GetGenericTypeDefinition() == base.MapType(typeof(IDictionary <,>)) && itemType == base.MapType(typeof(KeyValuePair <,>)).MakeGenericType(genArgs = type.GetGenericArguments())) { defaultType = base.MapType(typeof(Dictionary <,>)).MakeGenericType(genArgs); } else { defaultType = base.MapType(typeof(List <>)).MakeGenericType(new Type[] { itemType }); } } if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType)) { defaultType = null; } } }