internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) { #if !NO_GENERICS { Type tmp = Helpers.GetUnderlyingType(type); if (tmp != null) { type = tmp; } } #endif if (Helpers.IsEnum(type)) { if (allowComplexTypes && model != null) { // need to do this before checking the typecode; an int enum will report Int32 etc defaultWireType = WireType.Variant; return(new EnumSerializer(type, model.GetEnumMap(type))); } else { // enum is fine for adding as a meta-type defaultWireType = WireType.None; return(null); } } ProtoTypeCode code = Helpers.GetTypeCode(type); switch (code) { case ProtoTypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int32Serializer(model)); case ProtoTypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt32Serializer(model)); case ProtoTypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 64); return(new Int64Serializer(model)); case ProtoTypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 64); return(new UInt64Serializer(model)); case ProtoTypeCode.String: defaultWireType = WireType.String; if (asReference) { return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference)); } return(new StringSerializer(model)); case ProtoTypeCode.Single: defaultWireType = WireType.Fixed32; return(new SingleSerializer(model)); case ProtoTypeCode.Double: defaultWireType = WireType.Fixed64; return(new DoubleSerializer(model)); case ProtoTypeCode.Boolean: defaultWireType = WireType.Variant; return(new BooleanSerializer(model)); case ProtoTypeCode.DateTime: defaultWireType = GetDateTimeWireType(dataFormat); return(new DateTimeSerializer(model)); case ProtoTypeCode.Decimal: defaultWireType = WireType.String; return(new DecimalSerializer(model)); case ProtoTypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 32); return(new ByteSerializer(model)); case ProtoTypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 32); return(new SByteSerializer(model)); case ProtoTypeCode.Char: defaultWireType = WireType.Variant; return(new CharSerializer(model)); case ProtoTypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int16Serializer(model)); case ProtoTypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt16Serializer(model)); case ProtoTypeCode.TimeSpan: defaultWireType = GetDateTimeWireType(dataFormat); return(new TimeSpanSerializer(model)); case ProtoTypeCode.Guid: defaultWireType = WireType.String; return(new GuidSerializer(model)); case ProtoTypeCode.Uri: defaultWireType = WireType.String; return(new StringSerializer(model)); case ProtoTypeCode.ByteArray: defaultWireType = WireType.String; return(new BlobSerializer(model, overwriteList)); case ProtoTypeCode.Type: defaultWireType = WireType.String; return(new SystemTypeSerializer(model)); } IProtoSerializer parseable = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null; if (parseable != null) { defaultWireType = WireType.String; return(parseable); } if (allowComplexTypes && model != null) { int key = model.GetKey(type, false, true); if (asReference || dynamicType) { defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; BclHelpers.NetObjectOptions options = BclHelpers.NetObjectOptions.None; if (asReference) { options |= BclHelpers.NetObjectOptions.AsReference; } if (dynamicType) { options |= BclHelpers.NetObjectOptions.DynamicType; } if (key >= 0) { // exists if (asReference && Helpers.IsValueType(type)) { string message = "AsReference cannot be used with value-types"; if (type.Name == "KeyValuePair`2") { message += "; please see http://stackoverflow.com/q/14436606/"; } else { message += ": " + type.FullName; } throw new InvalidOperationException(message); } MetaType meta = model[type]; if (asReference && meta.IsAutoTuple) { options |= BclHelpers.NetObjectOptions.LateSet; } if (meta.UseConstructor) { options |= BclHelpers.NetObjectOptions.UseConstructor; } } return(new NetObjectSerializer(model, type, key, options)); } if (key >= 0) { defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; return(new SubItemSerializer(type, key, model[type], true)); } } defaultWireType = WireType.None; return(null); }
public IProtoSerializerWithWireType TryGetCoreSerializer(BinaryDataFormat dataFormat, Type type, out WireType defaultWireType, ref ValueFormat format, bool dynamicType, bool appendCollection, bool isPackedCollection, bool allowComplexTypes, ref object defaultValue) { if (format == ValueFormat.NotSpecified) { throw new ArgumentException("Format should be specified for TryGetCoreSerializer", nameof(format)); } if (format != ValueFormat.Compact && _model.ProtoCompatibility.SuppressValueEnhancedFormat) { throw new InvalidOperationException("TryGetCoreSerializer should receive final format with ProtoCompatibility already taken into account"); } Type originalType = type; #if !NO_GENERICS { Type tmp = Helpers.GetNullableUnderlyingType(type); if (tmp != null) { type = tmp; } } #endif defaultWireType = WireType.None; IProtoSerializerWithWireType ser = null; if (Helpers.IsEnum(type)) { if (allowComplexTypes && _model != null) { // need to do this before checking the typecode; an int enum will report Int32 etc defaultWireType = WireType.Variant; ser = new WireTypeDecorator(defaultWireType, new EnumSerializer(type, _model.GetEnumMap(type))); } else { // enum is fine for adding as a meta-type defaultWireType = WireType.None; return(null); } } if (ser == null) { ser = TryGetBasicTypeSerializer(dataFormat, type, out defaultWireType, !appendCollection); if (ser != null && Helpers.GetTypeCode(type) == ProtoTypeCode.Uri) { // should be after uri but uri should always be before collection if (defaultValue != null) { ser = new DefaultValueDecorator(_model, defaultValue, ser); defaultValue = null; } } } if (ser == null) { var parseable = _model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, _model) : null; if (parseable != null) { defaultWireType = WireType.String; ser = new WireTypeDecorator(defaultWireType, parseable); } } if (ser != null) { return((isPackedCollection || !allowComplexTypes) ? ser : DecorateValueSerializer(originalType, dynamicType ? dataFormat : (BinaryDataFormat?)null, ref format, ser)); } if (allowComplexTypes) { int baseKey = _model.GetKey(type, false, true); defaultWireType = WireType.StartGroup; if (baseKey >= 0 || dynamicType) { if (dynamicType) { return(new NetObjectValueDecorator(originalType, format == ValueFormat.Reference || format == ValueFormat.LateReference, dataFormat, !_model.ProtoCompatibility.SuppressNullWireType, _model)); } else if (format == ValueFormat.LateReference && CanTypeBeAsLateReferenceOnBuildStage(baseKey, _model)) { return(new NetObjectValueDecorator(originalType, baseKey, true, true, _model[type], !_model.ProtoCompatibility.SuppressNullWireType, _model)); } else if (MetaType.IsNetObjectValueDecoratorNecessary(_model, format)) { return(new NetObjectValueDecorator(originalType, baseKey, format == ValueFormat.Reference || format == ValueFormat.LateReference, false, _model[type], !_model.ProtoCompatibility.SuppressNullWireType, _model)); } else { return(new ModelTypeSerializer(type, baseKey, _model[type], _model)); } } } defaultWireType = WireType.None; return(null); }
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) { Type underlyingType = Helpers.GetUnderlyingType(type); if (underlyingType != null) { type = underlyingType; } if (Helpers.IsEnum(type)) { if (allowComplexTypes && model != null) { defaultWireType = WireType.Variant; return(new EnumSerializer(type, model.GetEnumMap(type))); } defaultWireType = WireType.None; return(null); } switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int32Serializer(model)); case ProtoTypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt32Serializer(model)); case ProtoTypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 64); return(new Int64Serializer(model)); case ProtoTypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 64); return(new UInt64Serializer(model)); case ProtoTypeCode.String: defaultWireType = WireType.String; if (asReference) { return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference)); } return(new StringSerializer(model)); case ProtoTypeCode.Single: defaultWireType = WireType.Fixed32; return(new SingleSerializer(model)); case ProtoTypeCode.Double: defaultWireType = WireType.Fixed64; return(new DoubleSerializer(model)); case ProtoTypeCode.Boolean: defaultWireType = WireType.Variant; return(new BooleanSerializer(model)); case ProtoTypeCode.DateTime: defaultWireType = GetDateTimeWireType(dataFormat); return(new DateTimeSerializer(model)); case ProtoTypeCode.Decimal: defaultWireType = WireType.String; return(new DecimalSerializer(model)); case ProtoTypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 32); return(new ByteSerializer(model)); case ProtoTypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 32); return(new SByteSerializer(model)); case ProtoTypeCode.Char: defaultWireType = WireType.Variant; return(new CharSerializer(model)); case ProtoTypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int16Serializer(model)); case ProtoTypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt16Serializer(model)); case ProtoTypeCode.TimeSpan: defaultWireType = GetDateTimeWireType(dataFormat); return(new TimeSpanSerializer(model)); case ProtoTypeCode.Guid: defaultWireType = WireType.String; return(new GuidSerializer(model)); case ProtoTypeCode.Uri: defaultWireType = WireType.String; return(new StringSerializer(model)); case ProtoTypeCode.ByteArray: defaultWireType = WireType.String; return(new BlobSerializer(model, overwriteList)); case ProtoTypeCode.Type: defaultWireType = WireType.String; return(new SystemTypeSerializer(model)); default: { IProtoSerializer protoSerializer = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null; if (protoSerializer != null) { defaultWireType = WireType.String; return(protoSerializer); } if (allowComplexTypes && model != null) { int key = model.GetKey(type, demand: false, getBaseKey: true); if (asReference || dynamicType) { defaultWireType = ((dataFormat == DataFormat.Group) ? WireType.StartGroup : WireType.String); BclHelpers.NetObjectOptions netObjectOptions = BclHelpers.NetObjectOptions.None; if (asReference) { netObjectOptions |= BclHelpers.NetObjectOptions.AsReference; } if (dynamicType) { netObjectOptions |= BclHelpers.NetObjectOptions.DynamicType; } if (key >= 0) { if (asReference && Helpers.IsValueType(type)) { string str = "AsReference cannot be used with value-types"; str = ((!(type.Name == "KeyValuePair`2")) ? (str + ": " + type.FullName) : (str + "; please see http://stackoverflow.com/q/14436606/")); throw new InvalidOperationException(str); } MetaType metaType = model[type]; if (asReference && metaType.IsAutoTuple) { netObjectOptions |= BclHelpers.NetObjectOptions.LateSet; } if (metaType.UseConstructor) { netObjectOptions |= BclHelpers.NetObjectOptions.UseConstructor; } } return(new NetObjectSerializer(model, type, key, netObjectOptions)); } if (key >= 0) { defaultWireType = ((dataFormat == DataFormat.Group) ? WireType.StartGroup : WireType.String); return(new SubItemSerializer(type, key, model[type], recursionCheck: true)); } } defaultWireType = WireType.None; return(null); } } }
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType) { #if !NO_GENERICS type = Nullable.GetUnderlyingType(type) ?? type; #endif if (type.IsEnum) { if (model != null) { // need to do this before checking the typecode; an int enum will report Int32 etc defaultWireType = WireType.Variant; return(new EnumSerializer(type, model.GetEnumMap(type))); } else { // enum is fine for adding as a meta-type defaultWireType = WireType.None; return(null); } } TypeCode code = Type.GetTypeCode(type); switch (code) { case TypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int32Serializer()); case TypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt32Serializer()); case TypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 64); return(new Int64Serializer()); case TypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 64); return(new UInt64Serializer()); case TypeCode.String: defaultWireType = WireType.String; if (asReference) { return(new NetObjectSerializer(typeof(string), 0, BclHelpers.NetObjectOptions.AsReference)); } return(new StringSerializer()); case TypeCode.Single: defaultWireType = WireType.Fixed32; return(new SingleSerializer()); case TypeCode.Double: defaultWireType = WireType.Fixed64; return(new DoubleSerializer()); case TypeCode.Boolean: defaultWireType = WireType.Variant; return(new BooleanSerializer()); case TypeCode.DateTime: defaultWireType = GetDateTimeWireType(dataFormat); return(new DateTimeSerializer()); case TypeCode.Decimal: defaultWireType = WireType.String; return(new DecimalSerializer()); case TypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 32); return(new ByteSerializer()); case TypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 32); return(new SByteSerializer()); case TypeCode.Char: defaultWireType = WireType.Variant; return(new CharSerializer()); case TypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 32); return(new Int16Serializer()); case TypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 32); return(new UInt16Serializer()); } if (type == typeof(TimeSpan)) { defaultWireType = GetDateTimeWireType(dataFormat); return(new TimeSpanSerializer()); } if (type == typeof(Guid)) { defaultWireType = WireType.String; return(new GuidSerializer()); } if (type == typeof(Uri)) { defaultWireType = WireType.String; return(new StringSerializer()); // treat as string; wrapped in decorator later } if (type == typeof(byte[])) { defaultWireType = WireType.String; return(new BlobSerializer()); } IProtoSerializer parseable = ParseableSerializer.TryCreate(type); if (parseable != null) { defaultWireType = WireType.String; return(parseable); } if (model != null) { int key = model.GetKey(type, false, true); if (asReference || dynamicType) { defaultWireType = WireType.String; BclHelpers.NetObjectOptions options = BclHelpers.NetObjectOptions.None; if (asReference) { options |= BclHelpers.NetObjectOptions.AsReference; } if (dynamicType) { options |= BclHelpers.NetObjectOptions.DynamicType; } if (key >= 0) { // exists if (model[type].UseConstructor) { options |= BclHelpers.NetObjectOptions.UseConstructor; } } return(new NetObjectSerializer(type, key, options)); } if (key >= 0) { defaultWireType = WireType.String; return(new SubItemSerializer(type, key, model[type], true)); } } defaultWireType = WireType.None; return(null); }
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, ProtoBuf.DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) { IProtoSerializer protoSerializer; Type underlyingType = Helpers.GetUnderlyingType(type); if (underlyingType != null) { type = underlyingType; } if (Helpers.IsEnum(type)) { if (!allowComplexTypes || model == null) { defaultWireType = WireType.None; return(null); } defaultWireType = WireType.Variant; return(new EnumSerializer(type, model.GetEnumMap(type))); } ProtoTypeCode typeCode = Helpers.GetTypeCode(type); switch (typeCode) { case ProtoTypeCode.Boolean: { defaultWireType = WireType.Variant; return(new BooleanSerializer(model)); } case ProtoTypeCode.Char: { defaultWireType = WireType.Variant; return(new CharSerializer(model)); } case ProtoTypeCode.SByte: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new SByteSerializer(model)); } case ProtoTypeCode.Byte: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new ByteSerializer(model)); } case ProtoTypeCode.Int16: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new Int16Serializer(model)); } case ProtoTypeCode.UInt16: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new UInt16Serializer(model)); } case ProtoTypeCode.Int32: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new Int32Serializer(model)); } case ProtoTypeCode.UInt32: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new UInt32Serializer(model)); } case ProtoTypeCode.Int64: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 64); return(new Int64Serializer(model)); } case ProtoTypeCode.UInt64: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 64); return(new UInt64Serializer(model)); } case ProtoTypeCode.Single: { defaultWireType = WireType.Fixed32; return(new SingleSerializer(model)); } case ProtoTypeCode.Double: { defaultWireType = WireType.Fixed64; return(new DoubleSerializer(model)); } case ProtoTypeCode.Decimal: { defaultWireType = WireType.String; return(new DecimalSerializer(model)); } case ProtoTypeCode.DateTime: { defaultWireType = ValueMember.GetDateTimeWireType(dataFormat); return(new DateTimeSerializer(model)); } case ProtoTypeCode.Unknown | ProtoTypeCode.DateTime: { Label0: if (model.AllowParseableTypes) { protoSerializer = ParseableSerializer.TryCreate(type, model); } else { protoSerializer = null; } IProtoSerializer protoSerializer1 = protoSerializer; if (protoSerializer1 != null) { defaultWireType = WireType.String; return(protoSerializer1); } if (allowComplexTypes && model != null) { int key = model.GetKey(type, false, true); if (asReference || dynamicType) { defaultWireType = (dataFormat == ProtoBuf.DataFormat.Group ? WireType.StartGroup : WireType.String); BclHelpers.NetObjectOptions netObjectOption = BclHelpers.NetObjectOptions.None; if (asReference) { netObjectOption = (BclHelpers.NetObjectOptions)((byte)(netObjectOption | BclHelpers.NetObjectOptions.AsReference)); } if (dynamicType) { netObjectOption = (BclHelpers.NetObjectOptions)((byte)(netObjectOption | BclHelpers.NetObjectOptions.DynamicType)); } if (key >= 0) { if (asReference && Helpers.IsValueType(type)) { string str = "AsReference cannot be used with value-types"; str = (type.Name != "KeyValuePair`2" ? string.Concat(str, ": ", type.FullName) : string.Concat(str, "; please see http://stackoverflow.com/q/14436606/")); throw new InvalidOperationException(str); } MetaType item = model[type]; if (asReference && item.IsAutoTuple) { netObjectOption = (BclHelpers.NetObjectOptions)((byte)(netObjectOption | BclHelpers.NetObjectOptions.LateSet)); } if (item.UseConstructor) { netObjectOption = (BclHelpers.NetObjectOptions)((byte)(netObjectOption | BclHelpers.NetObjectOptions.UseConstructor)); } } return(new NetObjectSerializer(model, type, key, netObjectOption)); } if (key >= 0) { defaultWireType = (dataFormat == ProtoBuf.DataFormat.Group ? WireType.StartGroup : WireType.String); return(new SubItemSerializer(type, key, model[type], true)); } } defaultWireType = WireType.None; return(null); } case ProtoTypeCode.String: { defaultWireType = WireType.String; if (!asReference) { return(new StringSerializer(model)); } return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference)); } default: { switch (typeCode) { case ProtoTypeCode.TimeSpan: { defaultWireType = ValueMember.GetDateTimeWireType(dataFormat); return(new TimeSpanSerializer(model)); } case ProtoTypeCode.ByteArray: { defaultWireType = WireType.String; return(new BlobSerializer(model, overwriteList)); } case ProtoTypeCode.Guid: { defaultWireType = WireType.String; return(new GuidSerializer(model)); } case ProtoTypeCode.Uri: { defaultWireType = WireType.String; return(new StringSerializer(model)); } case ProtoTypeCode.Type: { defaultWireType = WireType.String; return(new SystemTypeSerializer(model)); } default: { goto Label0; } } break; } } }