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)); // treat as string; wrapped in decorator later 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); }
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.Boolean: defaultWireType = WireType.Variant; return(new BooleanSerializer(model)); case ProtoTypeCode.Char: defaultWireType = WireType.Variant; return(new CharSerializer(model)); case ProtoTypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 0x20); return(new SByteSerializer(model)); case ProtoTypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 0x20); return(new ByteSerializer(model)); case ProtoTypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 0x20); return(new Int16Serializer(model)); case ProtoTypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 0x20); return(new UInt16Serializer(model)); case ProtoTypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 0x20); return(new Int32Serializer(model)); case ProtoTypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 0x20); return(new UInt32Serializer(model)); case ProtoTypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 0x40); return(new Int64Serializer(model)); case ProtoTypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 0x40); 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 = GetDateTimeWireType(dataFormat); return(new DateTimeSerializer(model)); case ProtoTypeCode.String: defaultWireType = WireType.String; if (!asReference) { return(new StringSerializer(model)); } return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference)); case ProtoTypeCode.TimeSpan: defaultWireType = 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)); } IProtoSerializer serializer = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null; if (serializer != null) { defaultWireType = WireType.String; return(serializer); } if (allowComplexTypes && (model != null)) { int key = model.GetKey(type, false, true); if (asReference || dynamicType) { defaultWireType = (dataFormat == DataFormat.Group) ? WireType.StartGroup : WireType.String; BclHelpers.NetObjectOptions none = BclHelpers.NetObjectOptions.None; if (asReference) { none = (BclHelpers.NetObjectOptions)((byte)(none | BclHelpers.NetObjectOptions.AsReference)); } if (dynamicType) { none = (BclHelpers.NetObjectOptions)((byte)(none | BclHelpers.NetObjectOptions.DynamicType)); } if (key >= 0) { if (asReference && Helpers.IsValueType(type)) { string message = "AsReference cannot be used with value-types"; if (type.Name == "KeyValuePair`2") { message = message + "; please see http://stackoverflow.com/q/14436606/"; } else { message = message + ": " + type.FullName; } throw new InvalidOperationException(message); } MetaType type3 = model[type]; if (asReference && type3.IsAutoTuple) { none = (BclHelpers.NetObjectOptions)((byte)(none | BclHelpers.NetObjectOptions.LateSet)); } if (type3.UseConstructor) { none = (BclHelpers.NetObjectOptions)((byte)(none | (BclHelpers.NetObjectOptions.None | BclHelpers.NetObjectOptions.UseConstructor))); } } return(new NetObjectSerializer(model, type, key, none)); } if (key >= 0) { defaultWireType = (dataFormat == DataFormat.Group) ? WireType.StartGroup : WireType.String; return(new SubItemSerializer(type, key, model[type], true)); } } defaultWireType = WireType.None; return(null); }