Exemple #1
0
        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;
            }
        }
Exemple #2
0
        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;
        }
Exemple #3
0
        // 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;
            }
        }
Exemple #5
0
 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;
 }
Exemple #6
0
        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;
            }
        }
Exemple #8
0
        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;
            }
        }
Exemple #9
0
 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;
     }
 }
Exemple #10
0
        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;
            }
        }
Exemple #11
0
 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);
         }
     }
 }
Exemple #12
0
 // 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);
         }
     }
 }
Exemple #13
0
        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);
        }
Exemple #14
0
        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;
		}
Exemple #17
0
        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);
            }
        }
Exemple #22
0
 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);
                    }
                }
            }
        }