public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members, Type[] kv) { if (ctor == null) { throw new ArgumentNullException("ctor"); } if (members == null) { throw new ArgumentNullException("members"); } this.ctor = ctor; this.members = members; this.tails = new IProtoSerializer[members.Length]; ParameterInfo[] parameters = ctor.GetParameters(); for (int i = 0; i < members.Length; i++) { WireType wireType; Type finalType = parameters[i].ParameterType; Type itemType = null, defaultType = null; MetaType.ResolveListTypes(model, finalType, ref itemType, ref defaultType); Type tmp = itemType == null ? finalType : itemType; bool asReference = false; int typeIndex = model.FindOrAddAuto(tmp, false, true, false); if (typeIndex >= 0) { asReference = model[tmp].AsReferenceDefault; } if (tmp.FullName == "ILRuntime.Runtime.Intepreter.ILTypeInstance") { tmp = kv [i]; } IProtoSerializer tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, tmp, out wireType, asReference, false, false, true), serializer; if (tail == null) { throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName); } tail = new TagDecorator(i + 1, wireType, false, tail); if (itemType == null) { serializer = tail; } else { if (finalType.IsArray) { serializer = new ArrayDecorator(model, tail, i + 1, false, wireType, finalType, false, false); } else { serializer = ListDecorator.Create(model, finalType, defaultType, tail, i + 1, false, wireType, true, false, false); } } tails[i] = serializer; } }
public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull) : base(tail) { Helpers.DebugAssert(arrayType != null, "arrayType should be non-null"); Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array; " + arrayType.FullName); this.itemType = arrayType.GetElementType(); #if NO_GENERICS Type underlyingItemType = itemType; #else Type underlyingItemType = supportNull ? itemType : (Helpers.GetUnderlyingType(itemType) ?? itemType); #endif Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType, "invalid tail"); Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof(byte)), "Should have used BlobSerializer"); if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) { throw new ArgumentOutOfRangeException("fieldNumber"); } if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) { throw new InvalidOperationException("Only simple data-types can use packed encoding"); } packedWireType = WireType.None; } this.fieldNumber = fieldNumber; this.packedWireType = packedWireType; if (writePacked) { options |= OPTIONS_WritePacked; } if (overwriteList) { options |= OPTIONS_OverwriteList; } if (supportNull) { options |= OPTIONS_SupportNull; } this.arrayType = arrayType; }
// Token: 0x06003513 RID: 13587 RVA: 0x001333E8 File Offset: 0x001317E8 public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull) : base(tail) { itemType = arrayType.GetElementType(); Type type = (!supportNull) ? (Helpers.GetUnderlyingType(itemType) ?? itemType) : itemType; if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) { throw new ArgumentOutOfRangeException("fieldNumber"); } if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) { throw new InvalidOperationException("Only simple data-types can use packed encoding"); } packedWireType = WireType.None; } this.fieldNumber = fieldNumber; this.packedWireType = packedWireType; if (writePacked) { options |= 1; } if (overwriteList) { options |= 2; } if (supportNull) { options |= 4; } this.arrayType = arrayType; }
public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members, bool asReference, bool baseTupleAsReference, bool forceIssueFakeHeader, bool useDynamicTypeWhenNeeded, bool supportNull) { if (ctor == null) throw new ArgumentNullException("ctor"); if (members == null) throw new ArgumentNullException("members"); this.ctor = ctor; this.members = members; this.tails = new IProtoSerializer[members.Length]; this.asReference = asReference; this.baseTupleAsReference = baseTupleAsReference; this.forceIssueFakeHeader = forceIssueFakeHeader; ParameterInfo[] parameters = ctor.GetParameters(); for(int i = 0 ; i < members.Length ; i++) { WireType wireType; Type finalType = parameters[i].ParameterType; Type itemType = null, defaultType = null; MetaType.ResolveListTypes(finalType, ref itemType, ref defaultType); Type tmp = itemType == null ? finalType : itemType; bool dynamicType = useDynamicTypeWhenNeeded && (tmp.IsInterface || tmp == typeof(object)); bool overrideSkipConstructor = i == 7; // if there are 8 class parameters the last one has to be a tuple IProtoSerializer tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, tmp, out wireType, asReference, dynamicType, false, overrideSkipConstructor, supportNull), serializer; if (tail == null) throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName); if (itemType != null && supportNull) { tail = new TagDecorator(NullDecorator.Tag, wireType, false, tail); tail = new NullDecorator(tail); tail = new TagDecorator(i + 1, WireType.StartGroup, false, tail); } else { tail = new TagDecorator(i + 1, wireType, false, tail); } if(itemType == null) { serializer = tail; } else { if (finalType.IsArray) { serializer = new ArrayDecorator(tail, i + 1, false, wireType, finalType, false, supportNull, asReference, false); } else { serializer = new ListDecorator(finalType, defaultType, tail, i + 1, false, wireType, true, false, supportNull, asReference, false, false); } } tails[i] = serializer; } }
public ArrayDecorator(IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList) : base(tail) { Helpers.DebugAssert(arrayType != null, "arrayType should be non-null"); Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array; " + arrayType.FullName); Helpers.DebugAssert(arrayType.GetElementType() == Tail.ExpectedType, "invalid tail"); Helpers.DebugAssert(Tail.ExpectedType != typeof(byte), "Should have used BlobSerializer"); if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) { throw new ArgumentOutOfRangeException("fieldNumber"); } if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) { throw new InvalidOperationException("Only simple data-types can use packed encoding"); } packedWireType = WireType.None; } this.fieldNumber = fieldNumber; this.packedWireType = packedWireType; if (writePacked) { options |= OPTIONS_WritePacked; } if (overwriteList) { options |= OPTIONS_OverwriteList; } this.arrayType = arrayType; this.itemType = Tail.ExpectedType; }
protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) { Type listType; #if NO_GENERICS listType = typeof(BasicList); #else listType = typeof(System.Collections.Generic.List <>).MakeGenericType(itemType); #endif using (Compiler.Local oldArr = ctx.GetLocalWithValue(ExpectedType, valueFrom)) using (Compiler.Local newArr = new Compiler.Local(ctx, ExpectedType)) using (Compiler.Local list = new Compiler.Local(ctx, listType)) { ctx.EmitCtor(listType); ctx.StoreValue(list); ListDecorator.EmitReadList(ctx, list, Tail, listType.GetMethod("Add"), packedWireType); // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList using (Compiler.Local oldLen = new ProtoBuf.Compiler.Local(ctx, typeof(int))) { ctx.LoadLength(oldArr, true); ctx.CopyValue(); ctx.StoreValue(oldLen); ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.Add(); ctx.CreateArray(itemType, null); // length is on the stack ctx.StoreValue(newArr); ctx.LoadValue(oldLen); Compiler.CodeLabel nothingToCopy = ctx.DefineLabel(); ctx.BranchIfFalse(nothingToCopy, true); ctx.LoadValue(oldArr); ctx.LoadValue(newArr); ctx.LoadValue(oldLen); Type[] argTypes = new Type[] { typeof(Array), typeof(int) }; ctx.EmitCall(ExpectedType.GetMethod("CopyTo", argTypes)); ctx.MarkLabel(nothingToCopy); ctx.LoadValue(list); ctx.LoadValue(newArr); ctx.LoadValue(oldLen); argTypes[0] = ExpectedType; // // prefer: CopyTo(T[], int) MethodInfo copyTo = listType.GetMethod("CopyTo", argTypes); if (copyTo == null) { // fallback: CopyTo(Array, int) argTypes[1] = typeof(Array); copyTo = listType.GetMethod("CopyTo", argTypes); } ctx.EmitCall(copyTo); } ctx.LoadValue(newArr); } }
public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members) { WireType wireType; IProtoSerializer arrayDecorator; if (ctor == null) { throw new ArgumentNullException("ctor"); } if (members == null) { throw new ArgumentNullException("members"); } this.ctor = ctor; this.members = members; this.tails = new IProtoSerializer[(int)members.Length]; ParameterInfo[] parameters = ctor.GetParameters(); for (int i = 0; i < (int)members.Length; i++) { Type parameterType = parameters[i].ParameterType; Type type = null; Type type1 = null; MetaType.ResolveListTypes(model, parameterType, ref type, ref type1); Type type2 = (type == null ? parameterType : type); bool asReferenceDefault = false; if (model.FindOrAddAuto(type2, false, true, false) >= 0) { asReferenceDefault = model[type2].AsReferenceDefault; } IProtoSerializer tagDecorator = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, type2, out wireType, asReferenceDefault, false, false, true); if (tagDecorator == null) { throw new InvalidOperationException(string.Concat("No serializer defined for type: ", type2.FullName)); } tagDecorator = new TagDecorator(i + 1, wireType, false, tagDecorator); if (type == null) { arrayDecorator = tagDecorator; } else if (!parameterType.IsArray) { arrayDecorator = ListDecorator.Create(model, parameterType, type1, tagDecorator, i + 1, false, wireType, true, false, false); } else { arrayDecorator = new ArrayDecorator(model, tagDecorator, i + 1, false, wireType, parameterType, false, false); } this.tails[i] = arrayDecorator; } }
public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members) { if (ctor == null) throw new ArgumentNullException("ctor"); if (members == null) throw new ArgumentNullException("members"); this.ctor = ctor; this.members = members; this.tails = new IProtoSerializer[members.Length]; ParameterInfo[] parameters = ctor.GetParameters(); for(int i = 0 ; i < members.Length ; i++) { WireType wireType; Type finalType = parameters[i].ParameterType; Type itemType = null, defaultType = null; MetaType.ResolveListTypes(model, finalType, ref itemType, ref defaultType); Type tmp = itemType == null ? finalType : itemType; bool asReference = false; int typeIndex = model.FindOrAddAuto(tmp, false, true, false); if (typeIndex >= 0) { asReference = model[tmp].AsReferenceDefault; } IProtoSerializer tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, tmp, out wireType, asReference, false, false, true), serializer; if (tail == null) { throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName); } tail = new TagDecorator(i + 1, wireType, false, tail); if(itemType == null) { serializer = tail; } else { if (finalType.IsArray) { serializer = new ArrayDecorator(model, tail, i + 1, false, wireType, finalType, false, false); } else { serializer = new ListDecorator(model, finalType, defaultType, tail, i + 1, false, wireType, true, false, false); } } tails[i] = serializer; } }
public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members) { if (ctor == null) { throw new ArgumentNullException("ctor"); } if (members == null) { throw new ArgumentNullException("members"); } this.ctor = ctor; this.members = members; this.tails = new IProtoSerializer[members.Length]; ParameterInfo[] parameters = ctor.GetParameters(); for (int i = 0; i < members.Length; i++) { Type parameterType = parameters[i].get_ParameterType(); Type type = null; Type concreteType = null; MetaType.ResolveListTypes(model, parameterType, ref type, ref concreteType); Type type2 = (type != null) ? type : parameterType; bool asReference = false; int num = model.FindOrAddAuto(type2, false, true, false); if (num >= 0) { asReference = model[type2].AsReferenceDefault; } WireType wireType; IProtoSerializer protoSerializer = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, type2, out wireType, asReference, false, false, true); if (protoSerializer == null) { throw new InvalidOperationException("No serializer defined for type: " + type2.get_FullName()); } protoSerializer = new TagDecorator(i + 1, wireType, false, protoSerializer); IProtoSerializer protoSerializer2; if (type == null) { protoSerializer2 = protoSerializer; } else if (parameterType.get_IsArray()) { protoSerializer2 = new ArrayDecorator(model, protoSerializer, i + 1, false, wireType, parameterType, false, false); } else { protoSerializer2 = ListDecorator.Create(model, parameterType, concreteType, protoSerializer, i + 1, false, wireType, true, false, false); } this.tails[i] = protoSerializer2; } }
public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members) { if (ctor == null) { throw new ArgumentNullException("ctor"); } if (members == null) { throw new ArgumentNullException("members"); } this.ctor = ctor; this.members = members; this.tails = new IProtoSerializer[members.Length]; ParameterInfo[] parameters = ctor.GetParameters(); for (int i = 0; i < members.Length; i++) { WireType wireType; Type finalType = parameters[i].ParameterType; Type itemType = null, defaultType = null; MetaType.ResolveListTypes(finalType, ref itemType, ref defaultType); Type tmp = itemType == null ? finalType : itemType; IProtoSerializer tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, tmp, out wireType, false, false, false), serializer; if (tail == null) { throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName); } tail = new TagDecorator(i + 1, wireType, false, tail); if (itemType == null) { serializer = tail; } else { if (finalType.IsArray) { serializer = new ArrayDecorator(tail, i + 1, false, wireType, finalType, false, false); } else { serializer = new ListDecorator(finalType, defaultType, tail, i + 1, false, wireType, true, false, false); } } tails[i] = serializer; } }
internal static void EmitReadList(CompilerContext ctx, Local list, IProtoSerializer tail, MethodInfo add, WireType packedWireType, bool castListForAdd) { using (Local local = new Local(ctx, ctx.MapType(typeof(int)))) { CodeLabel codeLabel = (packedWireType == WireType.None ? new CodeLabel() : ctx.DefineLabel()); if (packedWireType != WireType.None) { ctx.LoadReaderWriter(); ctx.LoadValue(typeof(ProtoReader).GetProperty("WireType")); ctx.LoadValue(2); ctx.BranchIfEqual(codeLabel, false); } ctx.LoadReaderWriter(); ctx.LoadValue(typeof(ProtoReader).GetProperty("FieldNumber")); ctx.StoreValue(local); CodeLabel codeLabel1 = ctx.DefineLabel(); ctx.MarkLabel(codeLabel1); ListDecorator.EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); ctx.LoadReaderWriter(); ctx.LoadValue(local); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("TryReadFieldHeader")); ctx.BranchIfTrue(codeLabel1, false); if (packedWireType != WireType.None) { CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.Branch(codeLabel2, false); ctx.MarkLabel(codeLabel); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem")); CodeLabel codeLabel3 = ctx.DefineLabel(); CodeLabel codeLabel4 = ctx.DefineLabel(); ctx.MarkLabel(codeLabel3); ctx.LoadValue((int)packedWireType); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("HasSubValue")); ctx.BranchIfFalse(codeLabel4, false); ListDecorator.EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); ctx.Branch(codeLabel3, false); ctx.MarkLabel(codeLabel4); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem")); ctx.MarkLabel(codeLabel2); } } }
// Token: 0x06000210 RID: 528 RVA: 0x0000E9F0 File Offset: 0x0000CBF0 protected ListDecorator(TypeModel model, Type declaredType, Type concreteType, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList, bool supportNull) : base(tail) { if (returnList) { this.options |= 8; } if (overwriteList) { this.options |= 16; } if (supportNull) { this.options |= 32; } if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) { throw new ArgumentOutOfRangeException("fieldNumber"); } if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) { throw new InvalidOperationException("Only simple data-types can use packed encoding"); } packedWireType = WireType.None; } this.fieldNumber = fieldNumber; if (writePacked) { this.options |= 4; } this.packedWireType = packedWireType; if (declaredType == null) { throw new ArgumentNullException("declaredType"); } if (declaredType.IsArray) { throw new ArgumentException("Cannot treat arrays as lists", "declaredType"); } this.declaredType = declaredType; this.concreteType = concreteType; if (this.RequireAdd) { bool flag; this.add = TypeModel.ResolveListAdd(model, declaredType, tail.ExpectedType, out flag); if (flag) { this.options |= 1; string fullName = declaredType.FullName; if (fullName != null && fullName.StartsWith("System.Data.Linq.EntitySet`1[[")) { this.options |= 2; } } if (this.add == null) { throw new InvalidOperationException("Unable to resolve a suitable Add method for " + declaredType.FullName); } } }
public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members) { if (ctor == (ConstructorInfo)null) { throw new ArgumentNullException("ctor"); } if (members == null) { throw new ArgumentNullException("members"); } this.ctor = ctor; this.members = members; tails = new IProtoSerializer[members.Length]; ParameterInfo[] parameters = ctor.GetParameters(); int num = 0; Type type2; while (true) { if (num < members.Length) { Type parameterType = parameters[num].ParameterType; Type type = null; Type concreteType = null; MetaType.ResolveListTypes(model, parameterType, ref type, ref concreteType); type2 = ((type == (Type)null) ? parameterType : type); bool asReference = false; if (model.FindOrAddAuto(type2, false, true, false) >= 0) { asReference = model[type2].AsReferenceDefault; } IProtoSerializer protoSerializer = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, type2, out WireType wireType, asReference, false, false, true); if (protoSerializer != null) { protoSerializer = new TagDecorator(num + 1, wireType, false, protoSerializer); IProtoSerializer protoSerializer2 = (!(type == (Type)null)) ? ((!parameterType.IsArray) ? ((ProtoDecoratorBase)ListDecorator.Create(model, parameterType, concreteType, protoSerializer, num + 1, false, wireType, true, false, false)) : ((ProtoDecoratorBase) new ArrayDecorator(model, protoSerializer, num + 1, false, wireType, parameterType, false, false))) : protoSerializer; tails[num] = protoSerializer2; num++; continue; } break; } return; } throw new InvalidOperationException("No serializer defined for type: " + type2.FullName); }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { Local localWithValue; Local local; Type type = ctx.MapType(typeof(List <>)); Type[] typeArray = new Type[] { this.itemType }; Type type1 = type.MakeGenericType(typeArray); Type expectedType = this.ExpectedType; if (this.AppendToCollection) { localWithValue = ctx.GetLocalWithValue(expectedType, valueFrom); } else { localWithValue = null; } using (Local local1 = localWithValue) { using (Local local2 = new Local(ctx, expectedType)) { using (Local local3 = new Local(ctx, type1)) { ctx.EmitCtor(type1); ctx.StoreValue(local3); ListDecorator.EmitReadList(ctx, local3, this.Tail, type1.GetMethod("Add"), this.packedWireType, false); if (this.AppendToCollection) { local = new Local(ctx, ctx.MapType(typeof(int))); } else { local = null; } using (Local local4 = local) { Type[] typeArray1 = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) }; Type[] typeArray2 = typeArray1; if (!this.AppendToCollection) { ctx.LoadAddress(local3, type1); ctx.LoadValue(type1.GetProperty("Count")); ctx.CreateArray(this.itemType, null); ctx.StoreValue(local2); ctx.LoadAddress(local3, type1); ctx.LoadValue(local2); ctx.LoadValue(0); } else { ctx.LoadLength(local1, true); ctx.CopyValue(); ctx.StoreValue(local4); ctx.LoadAddress(local3, type1); ctx.LoadValue(type1.GetProperty("Count")); ctx.Add(); ctx.CreateArray(this.itemType, null); ctx.StoreValue(local2); ctx.LoadValue(local4); CodeLabel codeLabel = ctx.DefineLabel(); ctx.BranchIfFalse(codeLabel, true); ctx.LoadValue(local1); ctx.LoadValue(local2); ctx.LoadValue(0); ctx.EmitCall(expectedType.GetMethod("CopyTo", typeArray2)); ctx.MarkLabel(codeLabel); ctx.LoadValue(local3); ctx.LoadValue(local2); ctx.LoadValue(local4); } typeArray2[0] = expectedType; MethodInfo method = type1.GetMethod("CopyTo", typeArray2); if (method == null) { typeArray2[1] = ctx.MapType(typeof(Array)); method = type1.GetMethod("CopyTo", typeArray2); } ctx.EmitCall(method); } ctx.LoadValue(local2); } } } }
protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) { Type listType; listType = ctx.MapType(typeof(System.Collections.Generic.List <>)).MakeGenericType(itemType); Type expected = ExpectedType; using (Compiler.Local oldArr = AppendToCollection ? ctx.GetLocalWithValue(expected, valueFrom) : null) using (Compiler.Local newArr = new Compiler.Local(ctx, expected)) using (Compiler.Local list = new Compiler.Local(ctx, listType)) { ctx.EmitCtor(listType); ctx.StoreValue(list); ListDecorator.EmitReadList(ctx, list, Tail, listType.GetMethod("Add"), packedWireType, false); // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList using (Compiler.Local oldLen = AppendToCollection ? new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))) : null) { Type[] copyToArrayInt32Args = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) }; if (AppendToCollection) { ctx.LoadLength(oldArr, true); ctx.CopyValue(); ctx.StoreValue(oldLen); ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.Add(); ctx.CreateArray(itemType, null); // length is on the stack ctx.StoreValue(newArr); ctx.LoadValue(oldLen); Compiler.CodeLabel nothingToCopy = ctx.DefineLabel(); ctx.BranchIfFalse(nothingToCopy, true); ctx.LoadValue(oldArr); ctx.LoadValue(newArr); ctx.LoadValue(0); // index in target ctx.EmitCall(expected.GetMethod("CopyTo", copyToArrayInt32Args)); ctx.MarkLabel(nothingToCopy); ctx.LoadValue(list); ctx.LoadValue(newArr); ctx.LoadValue(oldLen); } else { ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.CreateArray(itemType, null); ctx.StoreValue(newArr); ctx.LoadAddress(list, listType); ctx.LoadValue(newArr); ctx.LoadValue(0); } copyToArrayInt32Args[0] = expected; // // prefer: CopyTo(T[], int) MethodInfo copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); if (copyTo == null) { // fallback: CopyTo(Array, int) copyToArrayInt32Args[1] = ctx.MapType(typeof(Array)); copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); } ctx.EmitCall(copyTo); } ctx.LoadValue(newArr); } }
private IProtoSerializer GetNestedSerializer(BasicList nestedHierarchy, out WireType wireType) { IProtoSerializer ser = null; int listCount = nestedHierarchy.Count; wireType = WireType.None; bool hasAutoDynamicHandling = HasAutoDynamicHandling(nestedHierarchy); for (int i = listCount - 1; i >= 0; i--) { NestedItem item = (NestedItem)nestedHierarchy[i]; if (item.ItemType == null) { bool isDynamic = dynamicType; bool requiresDynamic = item.Type.IsInterface || item.Type == typeof (object); if (!isDynamic && autoDynamicType && requiresDynamic) { isDynamic = true; } else if (hasAutoDynamicHandling && requiresDynamic) { // for now just set isDynamic to true isDynamic = true; } ser = TryGetCoreSerializer(model, dataFormat, item.Type, out wireType, asReference, /*dynamicType*/isDynamic, OverwriteList, false, SupportNull); if (ser == null) throw new InvalidOperationException("No serializer defined for type: " + item.Type.FullName); if (listCount == 1) { ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); } } else { if (SupportNull) { if (IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser); ser = new NullDecorator(ser); ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser); } else { ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); } bool nested = listCount > 2 && i >= 1; if (item.Type.IsArray) { ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, item.Type, OverwriteList, SupportNull, AsReference, nested); } else { ser = new ListDecorator(item.Type, item.DefaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList, SupportNull, AsReference, nested, isValueMemberForCollectionBasedTypes); } } } return ser; }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { Local local; bool returnList = this.ReturnList; using (Local local1 = (this.AppendToCollection ? ctx.GetLocalWithValue(this.ExpectedType, valueFrom) : new Local(ctx, this.declaredType))) { if (!returnList || !this.AppendToCollection) { local = null; } else { local = new Local(ctx, this.ExpectedType); } using (Local local2 = local) { if (!this.AppendToCollection) { ctx.LoadNullRef(); ctx.StoreValue(local1); } else if (returnList) { ctx.LoadValue(local1); ctx.StoreValue(local2); } if (this.concreteType != null) { ctx.LoadValue(local1); CodeLabel codeLabel = ctx.DefineLabel(); ctx.BranchIfTrue(codeLabel, true); ctx.EmitCtor(this.concreteType); ctx.StoreValue(local1); ctx.MarkLabel(codeLabel); } bool flag = [email protected](this.declaredType); ListDecorator.EmitReadList(ctx, local1, this.Tail, this.@add, this.packedWireType, flag); if (returnList) { if (!this.AppendToCollection) { ctx.LoadValue(local1); } else { ctx.LoadValue(local2); ctx.LoadValue(local1); CodeLabel codeLabel1 = ctx.DefineLabel(); CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.BranchIfEqual(codeLabel1, true); ctx.LoadValue(local1); ctx.Branch(codeLabel2, true); ctx.MarkLabel(codeLabel1); ctx.LoadNullRef(); ctx.MarkLabel(codeLabel2); } } } } }
public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members) { if (ctor == null) { throw new ArgumentNullException("ctor"); } if (members == null) { throw new ArgumentNullException("members"); } this.ctor = ctor; this.members = members; tails = new IProtoSerializer[members.Length]; ParameterInfo[] parameters = ctor.GetParameters(); int num = 0; Type type; while (true) { if (num < members.Length) { Type parameterType = parameters[num].ParameterType; Type itemType = null; Type defaultType = null; MetaType.ResolveListTypes(model, parameterType, ref itemType, ref defaultType); type = ((itemType == null) ? parameterType : itemType); bool asReference = false; if (model.FindOrAddAuto(type, demand: false, addWithContractOnly: true, addEvenIfAutoDisabled: false) >= 0) { asReference = model[type].AsReferenceDefault; } IProtoSerializer protoSerializer = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, type, out WireType defaultWireType, asReference, dynamicType: false, overwriteList: false, allowComplexTypes: true); if (protoSerializer == null) { break; } protoSerializer = new TagDecorator(num + 1, defaultWireType, strict: false, protoSerializer); IProtoSerializer protoSerializer2 = (itemType != null) ? ((!parameterType.IsArray) ? ((ProtoDecoratorBase)ListDecorator.Create(model, parameterType, defaultType, protoSerializer, num + 1, writePacked: false, defaultWireType, returnList: true, overwriteList: false, supportNull: false)) : ((ProtoDecoratorBase) new ArrayDecorator(model, protoSerializer, num + 1, writePacked: false, defaultWireType, parameterType, overwriteList: false, supportNull: false))) : protoSerializer; tails[num] = protoSerializer2; num++; continue; } return; } throw new InvalidOperationException("No serializer defined for type: " + type.FullName); }
protected override void EmitWrite(CompilerContext ctx, Local valueFrom) { Type itemType = typeof(KeyValuePair <TKey, TValue>); MethodInfo moveNext, current, getEnumerator = ListDecorator.GetEnumeratorInfo( ExpectedType, itemType, out moveNext, out current); Type enumeratorType = getEnumerator.ReturnType; MethodInfo key = itemType.GetProperty(nameof(KeyValuePair <TKey, TValue> .Key)).GetGetMethod(), @value = itemType.GetProperty(nameof(KeyValuePair <TKey, TValue> .Value)).GetGetMethod(); using (Compiler.Local list = ctx.GetLocalWithValue(ExpectedType, valueFrom)) using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType)) using (Compiler.Local token = new Compiler.Local(ctx, typeof(SubItemToken))) using (Compiler.Local kvp = new Compiler.Local(ctx, itemType)) { ctx.LoadAddress(list, ExpectedType); ctx.EmitCall(getEnumerator, ExpectedType); ctx.StoreValue(iter); using (ctx.Using(iter)) { Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel(); ctx.Branch(next, false); ctx.MarkLabel(body); ctx.LoadAddress(iter, enumeratorType); ctx.EmitCall(current, enumeratorType); if (itemType != typeof(object) && current.ReturnType == typeof(object)) { ctx.CastFromObject(itemType); } ctx.StoreValue(kvp); ctx.LoadValue(fieldNumber); ctx.LoadValue((int)wireType); ctx.LoadWriter(true); ctx.EmitCall(ProtoWriter.GetStaticMethod("WriteFieldHeader")); ctx.LoadNullRef(); ctx.LoadWriter(true); ctx.EmitCall(ProtoWriter.GetStaticMethod("StartSubItem")); ctx.StoreValue(token); ctx.LoadAddress(kvp, itemType); ctx.EmitCall(key, itemType); ctx.WriteNullCheckedTail(typeof(TKey), keyTail, null); ctx.LoadAddress(kvp, itemType); ctx.EmitCall(value, itemType); ctx.WriteNullCheckedTail(typeof(TValue), Tail, null); ctx.LoadValue(token); ctx.LoadWriter(true); ctx.EmitCall(ProtoWriter.GetStaticMethod("EndSubItem")); ctx.MarkLabel(@next); ctx.LoadAddress(iter, enumeratorType); ctx.EmitCall(moveNext, enumeratorType); ctx.BranchIfTrue(body, false); } } }
private IProtoSerializer BuildSerializer() { WireType wireType; IProtoSerializer ser = GetCoreSerializer(itemType ?? memberType, out wireType); // apply tags ser = new TagDecorator(fieldNumber, wireType, isStrict, ser); // apply lists if appropriate if(itemType != null) { Helpers.DebugAssert(itemType == ser.ExpectedType, "Wrong type in the tail"); if (memberType.IsArray) { ser = new ArrayDecorator(ser, isPacked ? fieldNumber : 0, isPacked ? wireType : WireType.None); } else { ser = new ListDecorator(memberType, defaultType, ser, isPacked ? fieldNumber : 0, isPacked ? wireType : WireType.None); } } else if (defaultValue != null && !isRequired) { ser = new DefaultValueDecorator(defaultValue, ser); } if (memberType == typeof(Uri)) { ser = new UriDecorator(ser); } switch (member.MemberType) { case MemberTypes.Property: ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break; case MemberTypes.Field: ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break; default: throw new InvalidOperationException(); } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } return ser; }
private IProtoSerializer BuildSerializer() { int opaqueToken = 0; try { model.TakeLock(ref opaqueToken);// check nobody is still adding this type WireType wireType; Type finalType = itemType == null ? memberType : itemType; IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType); if (ser == null) throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); // apply tags if (itemType != null && SupportNull) { if(IsPacked) { throw new NotSupportedException("Packed encodings cannot support null values"); } ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser); ser = new NullDecorator(ser); ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser); } else { ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); } // apply lists if appropriate if (itemType != null) { #if NO_GENERICS Type underlyingItemType = itemType; #else Type underlyingItemType = SupportNull ? itemType : Nullable.GetUnderlyingType(itemType) ?? itemType; #endif Helpers.DebugAssert(underlyingItemType == ser.ExpectedType, "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType); if (memberType.IsArray) { ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull); } else { ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList, SupportNull); } } else if (defaultValue != null && !IsRequired) { ser = new DefaultValueDecorator(defaultValue, ser); } if (memberType == typeof(Uri)) { ser = new UriDecorator(ser); } if (member != null) { switch (member.MemberType) { case MemberTypes.Property: ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break; case MemberTypes.Field: ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break; default: throw new InvalidOperationException(); } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } } return ser; } finally { model.ReleaseLock(opaqueToken); } }
private IProtoSerializer BuildSerializer() { bool lockTaken = false; try { model.TakeLock(ref lockTaken);// check nobody is still adding this type WireType wireType; Type finalType = itemType == null ? memberType : itemType; IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType); if (ser == null) throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); // apply tags ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); // apply lists if appropriate if (itemType != null) { Helpers.DebugAssert(itemType == ser.ExpectedType, "Wrong type in the tail"); if (memberType.IsArray) { ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList); } else { ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList); } } else if (defaultValue != null && !IsRequired) { ser = new DefaultValueDecorator(defaultValue, ser); } if (memberType == typeof(Uri)) { ser = new UriDecorator(ser); } if (member != null) { switch (member.MemberType) { case MemberTypes.Property: ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break; case MemberTypes.Field: ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break; default: throw new InvalidOperationException(); } if (getSpecified != null || setSpecified != null) { ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); } } return ser; } finally { model.ReleaseLock(lockTaken); } }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { MethodInfo methodInfo; MethodInfo methodInfo1; Local localWithValue; if (base.AppendToCollection) { localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom); } else { localWithValue = null; } using (Local local = localWithValue) { using (Local local1 = new Local(ctx, this.builderFactory.ReturnType)) { ctx.EmitCall(this.builderFactory); ctx.StoreValue(local1); if (base.AppendToCollection) { CodeLabel codeLabel = ctx.DefineLabel(); if (!this.ExpectedType.IsValueType) { ctx.LoadValue(local); ctx.BranchIfFalse(codeLabel, false); } PropertyInfo property = Helpers.GetProperty(this.ExpectedType, "Length", false) ?? Helpers.GetProperty(this.ExpectedType, "Count", false) ?? Helpers.GetProperty(ImmutableCollectionDecorator.ResolveIReadOnlyCollection(this.ExpectedType, this.Tail.ExpectedType), "Count", false); ctx.LoadAddress(local, local.Type); ctx.EmitCall(Helpers.GetGetMethod(property, false, false)); ctx.BranchIfFalse(codeLabel, false); Type type = ctx.MapType(typeof(void)); if (this.addRange == null) { MethodInfo enumeratorInfo = base.GetEnumeratorInfo(ctx.Model, out methodInfo, out methodInfo1); Type returnType = enumeratorInfo.ReturnType; using (Local local2 = new Local(ctx, returnType)) { ctx.LoadAddress(local, this.ExpectedType); ctx.EmitCall(enumeratorInfo); ctx.StoreValue(local2); using (IDisposable disposable = ctx.Using(local2)) { CodeLabel codeLabel1 = ctx.DefineLabel(); CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.Branch(codeLabel2, false); ctx.MarkLabel(codeLabel1); ctx.LoadAddress(local1, local1.Type); ctx.LoadAddress(local2, returnType); ctx.EmitCall(methodInfo1); ctx.EmitCall(this.@add); if ([email protected] != null && [email protected] != type) { ctx.DiscardValue(); } ctx.MarkLabel(codeLabel2); ctx.LoadAddress(local2, returnType); ctx.EmitCall(methodInfo); ctx.BranchIfTrue(codeLabel1, false); } } } else { ctx.LoadValue(local1); ctx.LoadValue(local); ctx.EmitCall(this.addRange); if (this.addRange.ReturnType != null && [email protected] != type) { ctx.DiscardValue(); } } ctx.MarkLabel(codeLabel); } ListDecorator.EmitReadList(ctx, local1, this.Tail, this.@add, this.packedWireType, false); ctx.LoadAddress(local1, local1.Type); ctx.EmitCall(this.finish); if (this.ExpectedType != this.finish.ReturnType) { ctx.Cast(this.ExpectedType); } } } }