public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) { bool flag = (byte)(options & BclHelpers.NetObjectOptions.DynamicType) != 0; this.key = ((!flag) ? key : -1); this.type = ((!flag) ? type : model.MapType(typeof(object))); this.options = options; }
public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) { bool dynamicType = (options & BclHelpers.NetObjectOptions.DynamicType) != 0; this.key = dynamicType ? -1 : key; this.type = dynamicType ? model.MapType(typeof (object)) : type; this.options = options; }
public NetObjectSerializer(Type type, BclHelpers.NetObjectOptions options) { bool dynamicType = (options & BclHelpers.NetObjectOptions.DynamicType) != 0; ExpectedType = dynamicType ? typeof(object) : type; this.options = options; }
public static void WriteNetObject(object value, ProtoWriter dest, int key, BclHelpers.NetObjectOptions options) { bool flag; bool flag1; if (dest == null) { throw new ArgumentNullException("dest"); } bool flag2 = (byte)(options & BclHelpers.NetObjectOptions.DynamicType) != 0; bool flag3 = (byte)(options & BclHelpers.NetObjectOptions.AsReference) != 0; WireType wireType = dest.WireType; SubItemToken subItemToken = ProtoWriter.StartSubItem(null, dest); bool flag4 = true; if (flag3) { int num = dest.NetCache.AddObjectKey(value, out flag); ProtoWriter.WriteFieldHeader((flag ? 1 : 2), WireType.Variant, dest); ProtoWriter.WriteInt32(num, dest); if (flag) { flag4 = false; } } if (flag4) { if (flag2) { Type type = value.GetType(); if (!(value is string)) { key = dest.GetTypeKey(ref type); if (key < 0) { throw new InvalidOperationException(string.Concat("Dynamic type is not a contract-type: ", type.Name)); } } int num1 = dest.NetCache.AddObjectKey(type, out flag1); ProtoWriter.WriteFieldHeader((flag1 ? 3 : 4), WireType.Variant, dest); ProtoWriter.WriteInt32(num1, dest); if (!flag1) { ProtoWriter.WriteFieldHeader(8, WireType.String, dest); ProtoWriter.WriteString(dest.SerializeType(type), dest); } } ProtoWriter.WriteFieldHeader(10, wireType, dest); if (!(value is string)) { ProtoWriter.WriteObject(value, key, dest); } else { ProtoWriter.WriteString((string)value, dest); } } ProtoWriter.EndSubItem(subItemToken, dest); }
public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) { bool flag = ((byte)(options & BclHelpers.NetObjectOptions.DynamicType)) != 0; this.key = flag ? -1 : key; this.type = flag ? model.MapType(typeof(object)) : type; this.options = options; }
public NetObjectSerializer(Type type, int key, BclHelpers.NetObjectOptions options) { bool dynamicType = (options & BclHelpers.NetObjectOptions.DynamicType) != 0; this.key = dynamicType ? -1 : key; this.type = dynamicType ? typeof(object) : type; this.options = options; }
// Token: 0x060035A2 RID: 13730 RVA: 0x00134BA0 File Offset: 0x00132FA0 public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) { bool flag = (byte)(options & BclHelpers.NetObjectOptions.DynamicType) != 0; this.key = ((!flag) ? key : -1); this.type = ((!flag) ? type : model.MapType(typeof(object))); this.options = options; }
public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) { bool flag = (options & BclHelpers.NetObjectOptions.DynamicType) != 0; this.key = (flag ? (-1) : key); this.type = (flag ? model.MapType(typeof(object)) : type); this.options = options; }
public static void WriteNetObject(object value, ProtoWriter dest, int key, BclHelpers.NetObjectOptions options) { if (dest == null) { throw new ArgumentNullException("dest"); } bool flag = (byte)(options & BclHelpers.NetObjectOptions.DynamicType) != 0; bool flag2 = (byte)(options & BclHelpers.NetObjectOptions.AsReference) != 0; WireType wireType = dest.WireType; SubItemToken token = ProtoWriter.StartSubItem(null, dest); bool flag3 = true; if (flag2) { bool flag4; int value2 = dest.NetCache.AddObjectKey(value, out flag4); ProtoWriter.WriteFieldHeader((!flag4) ? 2 : 1, WireType.Variant, dest); ProtoWriter.WriteInt32(value2, dest); if (flag4) { flag3 = false; } } if (flag3) { if (flag) { Type type = value.GetType(); if (!(value is string)) { key = dest.GetTypeKey(ref type); if (key < 0) { throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.get_Name()); } } bool flag5; int value3 = dest.NetCache.AddObjectKey(type, out flag5); ProtoWriter.WriteFieldHeader((!flag5) ? 4 : 3, WireType.Variant, dest); ProtoWriter.WriteInt32(value3, dest); if (!flag5) { ProtoWriter.WriteFieldHeader(8, WireType.String, dest); ProtoWriter.WriteString(dest.SerializeType(type), dest); } } ProtoWriter.WriteFieldHeader(10, wireType, dest); if (value is string) { ProtoWriter.WriteString((string)value, dest); } else { ProtoWriter.WriteObject(value, key, dest); } } ProtoWriter.EndSubItem(token, dest); }
/// <summary> /// Dynamic type /// </summary> public NetObjectValueDecorator(Type dynamicBase, bool asReference, BinaryDataFormat dataFormatForDynamicBuiltins, bool allowNullWireType, RuntimeTypeModel model) : this(type : dynamicBase, asReference : asReference, asLateReference : false, allowNullWireType : allowNullWireType, model : model) { _dataFormatForDynamicBuiltins = dataFormatForDynamicBuiltins; _options |= BclHelpers.NetObjectOptions.DynamicType; // for late reference with dynamic type we need to get base type key from concrete // bacause dynamic types work with concrete type keys // but late reference - with bases // may be support later... }
// no need for special handling of !Nullable.HasValue - when boxing they will be applied NetObjectValueDecorator(Type type, bool asReference, bool asLateReference, bool allowNullWireType, RuntimeTypeModel model) { if (type == null) { throw new ArgumentNullException(nameof(type)); } _allowNullWireType = allowNullWireType; _options = BclHelpers.NetObjectOptions.UseConstructor; if (asReference) { _options |= BclHelpers.NetObjectOptions.AsReference; if (asLateReference) { _options |= BclHelpers.NetObjectOptions.WriteAsLateReference; } } else if (asLateReference) { throw new ArgumentException("Can't serialize as late reference when asReference = false", nameof(asReference)); } int baseKey = model.GetKey(type, false, true); int key = model.GetKey(type, false, false); if (!Helpers.IsValueType(type) && key >= 0 && baseKey >= 0 && ValueSerializerBuilder.CanTypeBeAsLateReferenceOnBuildStage(key, model, true)) { _lateReferenceTail = new LateReferenceSerializer(type, key, baseKey, model); } else if (asLateReference) { throw new ArgumentException("Can't use late reference with non-model or value type " + type.Name); } ProtoTypeCode typeCode = Helpers.GetTypeCode(type); // mind that this is set not for AsReference only // because AsReference may be switched in another version if (typeCode == ProtoTypeCode.String || typeCode == ProtoTypeCode.Type || typeCode == ProtoTypeCode.Uri) { _options |= BclHelpers.NetObjectOptions.LateSet; } // if this type is nullable it's ok // we'll unwrap it // and for non emit it's already boxed as not nullable this.ExpectedType = type; }
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); } } }
/// <summary> /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. /// </summary> public static SubItemToken ReadNetObject_Start(ref object value, ProtoReader source, ref Type type, BclHelpers.NetObjectOptions options, out bool isDynamic, out bool isLateReference, ref int typeKey, out int newObjectKey, out int newTypeRefKey, out bool shouldEnd) { #if FEAT_IKVM throw new NotSupportedException(); #else shouldEnd = false; newObjectKey = -1; newTypeRefKey = -1; isDynamic = false; isLateReference = false; SubItemToken token = ProtoReader.StartSubItem(source); int fieldNumber; if ((fieldNumber = source.ReadFieldHeader()) == 0) { // null handling value = null; return(token); } do { int tmp; switch (fieldNumber) { case FieldExistingObjectKey: tmp = source.ReadInt32(); value = source.NetCache.GetKeyedObject(tmp); break; case FieldNewObjectKey: newObjectKey = source.ReadInt32(); break; case FieldExistingTypeKey: tmp = source.ReadInt32(); type = (Type)source.NetCache.GetKeyedObject(tmp); typeKey = source.GetTypeKey(ref type); break; case FieldNewTypeKey: newTypeRefKey = source.ReadInt32(); break; case FieldTypeName: string typeName = source.ReadString(); type = source.DeserializeType(typeName); if (type == null) { throw new ProtoException("Unable to resolve type: " + typeName + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)"); } typeKey = source.GetTypeKey(ref type); isDynamic = true; break; case FieldLateReferenceObject: case FieldObject: if (fieldNumber == FieldLateReferenceObject) { isLateReference = true; } shouldEnd = true; bool wasNull = value == null; bool lateSet = wasNull && ((options & BclHelpers.NetObjectOptions.LateSet) != 0); if (newObjectKey >= 0 && !lateSet) { if (value == null) { source.TrapNextObject(newObjectKey); } else { source.NetCache.SetKeyedObject(newObjectKey, value); } if (newTypeRefKey >= 0) { source.NetCache.SetKeyedObject(newTypeRefKey, type); } } return(token); default: source.SkipField(); break; } } while ((fieldNumber = source.ReadFieldHeader()) > 0); return(token); #endif }
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); }
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); }
public object Read(object value, ProtoReader source) { var type = ExpectedType; if (source.WireType == WireType.Null) { return(Helpers.IsValueType(type) ? Activator.CreateInstance(type) : null); } if (!RequiresOldValue) { value = null; } bool shouldEnd; int newTypeRefKey; int newObjectKey; int typeKey = _baseKey; bool isDynamic; bool isLateReference; BclHelpers.NetObjectOptions options = _options; SubItemToken token = NetObjectHelpers.ReadNetObject_Start( ref value, source, ref type, options, out isDynamic, out isLateReference, ref typeKey, out newObjectKey, out newTypeRefKey, out shouldEnd); if (shouldEnd) { object oldValue = value; if (typeKey >= 0) { // can be only for builtins options &= ~BclHelpers.NetObjectOptions.LateSet; if (typeKey == _baseKey && _baseKeySerializer != null) { if (isLateReference) { if (_lateReferenceTail == null) { throw new ProtoException("Late reference can't be deserialized for type " + ExpectedType.Name); } value = _lateReferenceTail.Read(value, source); } else { value = _baseKeySerializer.Read(value, source); } } else { Debug.Assert(isDynamic); value = ProtoReader.ReadObject(value, typeKey, source); } } else { if (isDynamic) { if (source.TryReadBuiltinType(ref value, Helpers.GetTypeCode(type), true)) { options |= BclHelpers.NetObjectOptions.LateSet; } else { throw new ProtoException("Dynamic type is not a contract-type: " + type.Name); } } else { if (isLateReference) { if (_lateReferenceTail == null) { throw new ProtoException("Late reference can't be deserialized for type " + ExpectedType.Name); } value = _lateReferenceTail.Read(value, source); } else { if (_tail == null) { throw new ProtoException("Dynamic type expected but no type info was read"); } else { // ensure consistent behavior with emit version value = _tail.Read(_tail.RequiresOldValue ? value : null, source); } } } } NetObjectHelpers.ReadNetObject_EndWithNoteNewObject(value, source, oldValue, type, newObjectKey, newTypeRefKey, options, token); } else { if (Helpers.IsValueType(ExpectedType) && value == null) { value = Activator.CreateInstance(ExpectedType); } ProtoReader.EndSubItem(token, source); } return(value); }
// Token: 0x0600326E RID: 12910 RVA: 0x00126B54 File Offset: 0x00124F54 public static object ReadNetObject(object value, ProtoReader source, int key, Type type, BclHelpers.NetObjectOptions options) { SubItemToken token = ProtoReader.StartSubItem(source); int num = -1; int num2 = -1; int num3; while ((num3 = source.ReadFieldHeader()) > 0) { switch (num3) { case 1: { int key2 = source.ReadInt32(); value = source.NetCache.GetKeyedObject(key2); continue; } case 2: num = source.ReadInt32(); continue; case 3: { int key2 = source.ReadInt32(); type = (Type)source.NetCache.GetKeyedObject(key2); key = source.GetTypeKey(ref type); continue; } case 4: num2 = source.ReadInt32(); continue; case 8: { string text = source.ReadString(); type = source.DeserializeType(text); if (type == null) { throw new ProtoException("Unable to resolve type: " + text + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)"); } if (type == typeof(string)) { key = -1; } else { key = source.GetTypeKey(ref type); if (key < 0) { throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name); } } continue; } case 10: { bool flag = type == typeof(string); bool flag2 = value == null; bool flag3 = flag2 && (flag || (byte)(options & BclHelpers.NetObjectOptions.LateSet) != 0); if (num >= 0 && !flag3) { if (value == null) { source.TrapNextObject(num); } else { source.NetCache.SetKeyedObject(num, value); } if (num2 >= 0) { source.NetCache.SetKeyedObject(num2, type); } } object obj = value; if (flag) { value = source.ReadString(); } else { value = ProtoReader.ReadTypedObject(obj, key, source, type); } if (num >= 0) { if (flag2 && !flag3) { obj = source.NetCache.GetKeyedObject(num); } if (flag3) { source.NetCache.SetKeyedObject(num, value); if (num2 >= 0) { source.NetCache.SetKeyedObject(num2, type); } } } if (num >= 0 && !flag3 && !object.ReferenceEquals(obj, value)) { throw new ProtoException("A reference-tracked object changed reference during deserialization"); } if (num < 0 && num2 >= 0) { source.NetCache.SetKeyedObject(num2, type); } continue; } } source.SkipField(); } if (num >= 0 && (byte)(options & BclHelpers.NetObjectOptions.AsReference) == 0) { throw new ProtoException("Object key in input stream, but reference-tracking was not expected"); } ProtoReader.EndSubItem(token, source); return(value); }
static void ReadNetObject_NoteNewObject(object value, ProtoReader source, object oldValue, Type type, int newObjectKey, int newTypeRefKey, BclHelpers.NetObjectOptions options) { #if FEAT_IKVM throw new NotSupportedException(); #else // late set may become here true e.g. for dynamic string bool wasNull = oldValue == null; bool lateSet = wasNull && ((options & BclHelpers.NetObjectOptions.LateSet) != 0); if (newObjectKey >= 0) { if (wasNull && !lateSet) { // this both ensures (via exception) that it *was* set, and makes sure we don't shout // about changed references oldValue = source.NetCache.GetKeyedObject(newObjectKey); if (!ReferenceEquals(oldValue, value)) { throw new ProtoException("A reference-tracked object changed reference during deserialization"); } } if (lateSet) { source.NetCache.SetKeyedObject(newObjectKey, value, true); } } if (newTypeRefKey >= 0) { source.NetCache.SetKeyedObject(newTypeRefKey, type); } #endif }
// this method is split because we need to insert our implementation inside and it's hard to deal with delegates in emit public static void ReadNetObject_EndWithNoteNewObject(object value, ProtoReader source, object oldValue, Type type, int newObjectKey, int newTypeRefKey, BclHelpers.NetObjectOptions options, SubItemToken token) { ReadNetObject_NoteNewObject(value, source, oldValue, type, newObjectKey, newTypeRefKey, options); ProtoReader.EndSubItem(token, source); }
public static object ReadNetObject(object value, ProtoReader source, int key, Type type, BclHelpers.NetObjectOptions options) { int num; bool flag; SubItemToken subItemToken = ProtoReader.StartSubItem(source); int num1 = -1; int num2 = -1; do { Label0: int num3 = source.ReadFieldHeader(); int num4 = num3; if (num3 <= 0) { if (num1 >= 0 && (byte)(options & BclHelpers.NetObjectOptions.AsReference) == 0) { throw new ProtoException("Object key in input stream, but reference-tracking was not expected"); } ProtoReader.EndSubItem(subItemToken, source); return(value); } switch (num4) { case 1: { num = source.ReadInt32(); value = source.NetCache.GetKeyedObject(num); goto Label0; } case 2: { num1 = source.ReadInt32(); goto Label0; } case 3: { num = source.ReadInt32(); type = (Type)source.NetCache.GetKeyedObject(num); key = source.GetTypeKey(ref type); goto Label0; } case 4: { num2 = source.ReadInt32(); goto Label0; } case 5: case 6: case 7: case 9: { source.SkipField(); goto Label0; } case 8: { string str = source.ReadString(); type = source.DeserializeType(str); if (type == null) { throw new ProtoException(string.Concat("Unable to resolve type: ", str, " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)")); } if (type != typeof(string)) { key = source.GetTypeKey(ref type); continue; } else { key = -1; goto Label0; } } case 10: { bool flag1 = type == typeof(string); bool flag2 = value == null; if (!flag2) { flag = false; } else { flag = (flag1 ? true : (byte)(options & BclHelpers.NetObjectOptions.LateSet) != 0); } bool flag3 = flag; if (num1 >= 0 && !flag3) { if (value != null) { source.NetCache.SetKeyedObject(num1, value); } else { source.TrapNextObject(num1); } if (num2 >= 0) { source.NetCache.SetKeyedObject(num2, type); } } object keyedObject = value; if (!flag1) { value = ProtoReader.ReadTypedObject(keyedObject, key, source, type); } else { value = source.ReadString(); } if (num1 >= 0) { if (flag2 && !flag3) { keyedObject = source.NetCache.GetKeyedObject(num1); } if (flag3) { source.NetCache.SetKeyedObject(num1, value); if (num2 >= 0) { source.NetCache.SetKeyedObject(num2, type); } } } if (num1 >= 0 && !flag3 && !object.ReferenceEquals(keyedObject, value)) { throw new ProtoException("A reference-tracked object changed reference during deserialization"); } if (num1 >= 0 || num2 < 0) { goto Label0; } source.NetCache.SetKeyedObject(num2, type); goto Label0; } default: { goto case 9; } } }while (key >= 0); throw new InvalidOperationException(string.Concat("Dynamic type is not a contract-type: ", type.Name)); }
/// <summary> /// Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. /// </summary> public static SubItemToken WriteNetObject_Start(object value, ProtoWriter dest, BclHelpers.NetObjectOptions options, out int dynamicTypeKey, out bool writeObject) { #if FEAT_IKVM throw new NotSupportedException(); #else if (dest == null) { throw new ArgumentNullException(nameof(dest)); } dynamicTypeKey = -1; // length not prefixed to not move data in buffer twice just because of NetObject (will be another nested inside) SubItemToken token = ProtoWriter.StartSubItem(null, false, dest); if (value == null) { // null handling writeObject = false; return(token); } // even root object can be wrapped with collection // so it's not true root writeObject = true; if ((options & BclHelpers.NetObjectOptions.AsReference) != 0) { bool existing; int objectKey = dest.NetCache.AddObjectKey(value, out existing); ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant, dest); ProtoWriter.WriteInt32(objectKey, dest); if (existing) { writeObject = false; } } if (writeObject) { if ((options & BclHelpers.NetObjectOptions.DynamicType) != 0) { bool existing; Type type = value.GetType(); dynamicTypeKey = dest.GetTypeKey(ref type); int typeRefKey = dest.NetCache.AddObjectKey(type, out existing); ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, dest); ProtoWriter.WriteInt32(typeRefKey, dest); if (!existing) { ProtoWriter.WriteFieldHeader(FieldTypeName, WireType.String, dest); ProtoWriter.WriteString(dest.SerializeType(type), dest); } } // do nothing, write will be outside ProtoWriter.WriteFieldHeaderBegin((options & BclHelpers.NetObjectOptions.WriteAsLateReference) != 0 ? FieldLateReferenceObject : FieldObject, dest); } return(token); #endif }
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; } } }