Example #1
0
        /// <summary>
        /// Adds a known sub-type to the inheritance model
        /// </summary>
        public MetaType AddSubType(int fieldNumber, Type derivedType)
        {
            if (derivedType == null) throw new ArgumentNullException("derivedType");
            if (fieldNumber < 1) throw new ArgumentOutOfRangeException("fieldNumber");
            if (!(type.IsClass || type.IsInterface) || type.IsSealed) {
                throw new InvalidOperationException("Sub-types can only be added to non-sealed classes");
            }
            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                throw new ArgumentException("Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be subclassed");
            }
            if (typeof(IEnumerable).IsAssignableFrom(derivedType))
            {
                throw new ArgumentException("Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be used as a subclass");
            }
            ThrowIfFrozen();
            MetaType derivedMeta = model[derivedType];
            derivedMeta.ThrowIfFrozen();
            SubType subType = new SubType(fieldNumber, derivedMeta);
            ThrowIfFrozen();

            derivedMeta.SetBaseType(this); // includes ThrowIfFrozen
            if (subTypes == null) subTypes = new BasicList();
            subTypes.Add(subType);
            return this;
        }
Example #2
0
            public Group(int first)

            {
                this.First = first;

                this.Items = new BasicList();
            }
        private void CascadeDependents(BasicList list, MetaType metaType)
        {
            MetaType surrogateOrBaseOrSelf;

            if (metaType.IsList)
            {
                Type listItemType = TypeModel.GetListItemType(this, metaType.Type);
                if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, listItemType, out WireType _, asReference: false, dynamicType: false, overwriteList: false, allowComplexTypes: false) != null)
                {
                    return;
                }
                int num = FindOrAddAuto(listItemType, demand: false, addWithContractOnly: false, addEvenIfAutoDisabled: false);
                if (num >= 0)
                {
                    surrogateOrBaseOrSelf = ((MetaType)types[num]).GetSurrogateOrBaseOrSelf(deep: false);
                    if (!list.Contains(surrogateOrBaseOrSelf))
                    {
                        list.Add(surrogateOrBaseOrSelf);
                        CascadeDependents(list, surrogateOrBaseOrSelf);
                    }
                }
                return;
            }
            if (metaType.IsAutoTuple)
            {
                if (MetaType.ResolveTupleConstructor(metaType.Type, out MemberInfo[] mappedMembers) != null)
        // Token: 0x06000371 RID: 881 RVA: 0x00012D84 File Offset: 0x00010F84
        internal IProtoSerializer TryGetBasicTypeSerializer(Type type)
        {
            int num = this.basicTypes.IndexOf(RuntimeTypeModel.BasicTypeFinder, type);

            if (num >= 0)
            {
                return(((RuntimeTypeModel.BasicType) this.basicTypes[num]).Serializer);
            }
            BasicList        obj = this.basicTypes;
            IProtoSerializer result;

            lock (obj)
            {
                num = this.basicTypes.IndexOf(RuntimeTypeModel.BasicTypeFinder, type);
                if (num >= 0)
                {
                    result = ((RuntimeTypeModel.BasicType) this.basicTypes[num]).Serializer;
                }
                else
                {
                    WireType         wireType;
                    IProtoSerializer protoSerializer = (MetaType.GetContractFamily(this, type, null) == MetaType.AttributeFamily.None) ? ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out wireType, false, false, false, false) : null;
                    if (protoSerializer != null)
                    {
                        this.basicTypes.Add(new RuntimeTypeModel.BasicType(type, protoSerializer));
                    }
                    result = protoSerializer;
                }
            }
            return(result);
        }
Example #5
0
        internal static BasicList GetContiguousGroups(int[] keys, object[] values)
        {
            if (keys == null)
            {
                throw new ArgumentNullException("keys");
            }
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }
            if (values.Length < keys.Length)
            {
                throw new ArgumentException("Not all keys are covered by values", "values");
            }
            BasicList outer = new BasicList();
            Group     group = null;

            for (int i = 0; i < keys.Length; i++)
            {
                if (i == 0 || keys[i] != keys[i - 1])
                {
                    group = null;
                }
                if (group == null)
                {
                    group = new Group(keys[i]);
                    outer.Add(group);
                }
                group.Items.Add(values[i]);
            }
            return(outer);
        }
Example #6
0
 private void CascadeDependents(BasicList list, MetaType metaType)
 {
     if (metaType.IsList)
     {
         Type listItemType = TypeModel.GetListItemType(this, metaType.Type);
         if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, listItemType, out WireType _, false, false, false, false) == null)
         {
             int num = FindOrAddAuto(listItemType, false, false, false);
             if (num >= 0)
             {
                 MetaType surrogateOrBaseOrSelf = ((MetaType)types[num]).GetSurrogateOrBaseOrSelf(false);
                 if (!list.Contains(surrogateOrBaseOrSelf))
                 {
                     list.Add(surrogateOrBaseOrSelf);
                     CascadeDependents(list, surrogateOrBaseOrSelf);
                 }
             }
         }
     }
     else
     {
         MetaType surrogateOrBaseOrSelf;
         if (metaType.IsAutoTuple)
         {
             if (MetaType.ResolveTupleConstructor(metaType.Type, out MemberInfo[] array) != (ConstructorInfo)null)
Example #7
0
        /// <summary>
        /// Adds a known sub-type to the inheritance model
        /// </summary>
        public MetaType AddSubType(int fieldNumber, Type derivedType)
        {
            if (!(type.IsClass || type.IsInterface) || type.IsSealed)
            {
                throw new InvalidOperationException("Sub-types can only be added to non-sealed classes");
            }
            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                throw new ArgumentException("Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be subclassed");
            }
            ThrowIfFrozen();
            MetaType derivedMeta = model[derivedType];

            derivedMeta.ThrowIfFrozen();
            SubType subType = new SubType(fieldNumber, derivedMeta);

            ThrowIfFrozen();

            derivedMeta.SetBaseType(this); // includes ThrowIfFrozen
            if (subTypes == null)
            {
                subTypes = new BasicList();
            }
            subTypes.Add(subType);
            return(this);
        }
Example #8
0
        private IProtoTypeSerializer BuildSerializer()
        {
            if (surrogate != null)
            {
                return(new SurrogateSerializer(type, model[surrogate].Serializer));
            }

            fields.Trim();
            int fieldCount   = fields.Count;
            int subTypeCount = subTypes == null ? 0 : subTypes.Count;

            int[] fieldNumbers             = new int[fieldCount + subTypeCount];
            IProtoSerializer[] serializers = new IProtoSerializer[fieldCount + subTypeCount];
            int i = 0;

            if (subTypeCount != 0)
            {
                foreach (SubType subType in subTypes)
                {
                    fieldNumbers[i]  = subType.FieldNumber;
                    serializers[i++] = subType.Serializer;
                }
            }
            if (fieldCount != 0)
            {
                foreach (ValueMember member in fields)
                {
                    fieldNumbers[i]  = member.FieldNumber;
                    serializers[i++] = member.Serializer;
                }
            }

            BasicList baseCtorCallbacks = null;
            MetaType  tmp = BaseType;

            while (tmp != null)
            {
                MethodInfo method = tmp.HasCallbacks ? tmp.Callbacks.BeforeDeserialize : null;
                if (method != null)
                {
                    if (baseCtorCallbacks == null)
                    {
                        baseCtorCallbacks = new BasicList();
                    }
                    baseCtorCallbacks.Add(method);
                }
                tmp = tmp.BaseType;
            }
            MethodInfo[] arr = null;
            if (baseCtorCallbacks != null)
            {
                arr = new MethodInfo[baseCtorCallbacks.Count];
                baseCtorCallbacks.CopyTo(arr, 0);
                Array.Reverse(arr);
            }
            return(new TypeSerializer(type, fieldNumbers, serializers, arr, baseType == null, useConstructor, callbacks));
        }
Example #9
0
 static public int get_Count(IntPtr l)
 {
     try {
         ProtoBuf.Meta.BasicList self = (ProtoBuf.Meta.BasicList)checkSelf(l);
         pushValue(l, true);
         pushValue(l, self.Count);
         return(2);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
Example #10
0
 static public int Trim(IntPtr l)
 {
     try {
         ProtoBuf.Meta.BasicList self = (ProtoBuf.Meta.BasicList)checkSelf(l);
         self.Trim();
         pushValue(l, true);
         return(1);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
Example #11
0
 static public int constructor(IntPtr l)
 {
     try {
         ProtoBuf.Meta.BasicList o;
         o = new ProtoBuf.Meta.BasicList();
         pushValue(l, true);
         pushValue(l, o);
         return(2);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
        /// <summary>
        /// Adds a known sub-type to the inheritance model
        /// </summary>
        public MetaType AddSubType(int fieldNumber, Type derivedType)
        {
            if (!type.IsClass || type.IsSealed) {
                throw new InvalidOperationException("Sub-types can only be adedd to non-sealed classes");
            }
            MetaType derivedMeta = model[derivedType];
            SubType subType = new SubType(fieldNumber, derivedMeta);
            ThrowIfFrozen();

            derivedMeta.SetBaseType(this); // includes ThrowIfFrozen
            if (subTypes == null) subTypes = new BasicList();
            subTypes.Add(subType);
            return this;
        }
Example #13
0
 static public int getItem(IntPtr l)
 {
     try {
         ProtoBuf.Meta.BasicList self = (ProtoBuf.Meta.BasicList)checkSelf(l);
         int v;
         checkType(l, 2, out v);
         var ret = self[v];
         pushValue(l, true);
         pushValue(l, ret);
         return(2);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
Example #14
0
 static public int Add(IntPtr l)
 {
     try {
         ProtoBuf.Meta.BasicList self = (ProtoBuf.Meta.BasicList)checkSelf(l);
         System.Object           a1;
         checkType(l, 2, out a1);
         var ret = self.Add(a1);
         pushValue(l, true);
         pushValue(l, ret);
         return(2);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
Example #15
0
 private static void TestEnumerableListPatterns(TypeModel model, BasicList candidates, Type iType)
 {
     if (iType.IsGenericType)
     {
         Type genericTypeDefinition = iType.GetGenericTypeDefinition();
         if (!(genericTypeDefinition == model.MapType(typeof(IEnumerable <>))) && !(genericTypeDefinition == model.MapType(typeof(ICollection <>))) && !(genericTypeDefinition.FullName == "System.Collections.Concurrent.IProducerConsumerCollection`1"))
         {
             return;
         }
         Type[] genericArguments = iType.GetGenericArguments();
         if (!candidates.Contains(genericArguments[0]))
         {
             candidates.Add(genericArguments[0]);
         }
     }
 }
Example #16
0
        /// <summary>
        /// Adds a known sub-type to the inheritance model
        /// </summary>
        public MetaType AddSubType(int fieldNumber, Type derivedType)
        {
            if (!type.IsClass || type.IsSealed)
            {
                throw new InvalidOperationException("Sub-types can only be adedd to non-sealed classes");
            }
            MetaType derivedMeta = model[derivedType];
            SubType  subType     = new SubType(fieldNumber, derivedMeta);

            ThrowIfFrozen();

            derivedMeta.SetBaseType(this); // includes ThrowIfFrozen
            if (subTypes == null)
            {
                subTypes = new BasicList();
            }
            subTypes.Add(subType);
            return(this);
        }
Example #17
0
 internal NodeEnumerator(BasicList.Node node)
 {
     this.position = -1;
     this.node = node;
 }
        public override string GetSchema(Type type)
        {
            BasicList basicList = new BasicList();
            MetaType  metaType  = null;
            bool      flag      = false;

            if (type == null)
            {
                BasicList.NodeEnumerator enumerator = types.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    MetaType surrogateOrBaseOrSelf = ((MetaType)enumerator.Current).GetSurrogateOrBaseOrSelf(deep: false);
                    if (!basicList.Contains(surrogateOrBaseOrSelf))
                    {
                        basicList.Add(surrogateOrBaseOrSelf);
                        CascadeDependents(basicList, surrogateOrBaseOrSelf);
                    }
                }
            }
            else
            {
                Type underlyingType = Helpers.GetUnderlyingType(type);
                if (underlyingType != null)
                {
                    type = underlyingType;
                }
                flag = (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out WireType _, asReference: false, dynamicType: false, overwriteList: false, allowComplexTypes: false) != null);
                if (!flag)
                {
                    int num = FindOrAddAuto(type, demand: false, addWithContractOnly: false, addEvenIfAutoDisabled: false);
                    if (num < 0)
                    {
                        throw new ArgumentException("The type specified is not a contract-type", "type");
                    }
                    metaType = ((MetaType)types[num]).GetSurrogateOrBaseOrSelf(deep: false);
                    basicList.Add(metaType);
                    CascadeDependents(basicList, metaType);
                }
            }
            StringBuilder stringBuilder = new StringBuilder();
            string        text          = null;

            if (!flag)
            {
                foreach (MetaType item in (IEnumerable)((metaType == null) ? types : basicList))
                {
                    if (!item.IsList)
                    {
                        string @namespace = item.Type.Namespace;
                        if (!Helpers.IsNullOrEmpty(@namespace) && [email protected]("System."))
                        {
                            if (text == null)
                            {
                                text = @namespace;
                            }
                            else if (!(text == @namespace))
                            {
                                text = null;
                                break;
                            }
                        }
                    }
                }
            }
            if (!Helpers.IsNullOrEmpty(text))
            {
                stringBuilder.Append("package ").Append(text).Append(';');
                Helpers.AppendLine(stringBuilder);
            }
            bool          requiresBclImport = false;
            StringBuilder stringBuilder2    = new StringBuilder();

            MetaType[] array = new MetaType[basicList.Count];
            basicList.CopyTo(array, 0);
            Array.Sort(array, MetaType.Comparer.Default);
            if (flag)
            {
                Helpers.AppendLine(stringBuilder2).Append("message ").Append(type.Name)
                .Append(" {");
                MetaType.NewLine(stringBuilder2, 1).Append("optional ").Append(GetSchemaTypeName(type, DataFormat.Default, asReference: false, dynamicType: false, ref requiresBclImport))
                .Append(" value = 1;");
                Helpers.AppendLine(stringBuilder2).Append('}');
            }
            else
            {
                foreach (MetaType metaType3 in array)
                {
                    if (!metaType3.IsList || metaType3 == metaType)
                    {
                        metaType3.WriteSchema(stringBuilder2, 0, ref requiresBclImport);
                    }
                }
            }
            if (requiresBclImport)
            {
                stringBuilder.Append("import \"bcl.proto\"; // schema for protobuf-net's handling of core .NET types");
                Helpers.AppendLine(stringBuilder);
            }
            return(Helpers.AppendLine(stringBuilder.Append(stringBuilder2)).ToString());
        }
 // Token: 0x0600036A RID: 874 RVA: 0x00012A1C File Offset: 0x00010C1C
 private void CascadeDependents(BasicList list, MetaType metaType)
 {
     if (metaType.IsList)
     {
         Type     listItemType = TypeModel.GetListItemType(this, metaType.Type);
         WireType wireType;
         if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, listItemType, out wireType, false, false, false, false) == null)
         {
             int num = this.FindOrAddAuto(listItemType, false, false, false);
             if (num >= 0)
             {
                 MetaType metaType2 = ((MetaType)this.types[num]).GetSurrogateOrBaseOrSelf(false);
                 if (!list.Contains(metaType2))
                 {
                     list.Add(metaType2);
                     this.CascadeDependents(list, metaType2);
                     return;
                 }
             }
         }
     }
     else
     {
         MetaType metaType2;
         if (metaType.IsAutoTuple)
         {
             MemberInfo[] array;
             if (MetaType.ResolveTupleConstructor(metaType.Type, out array) != null)
             {
                 for (int i = 0; i < array.Length; i++)
                 {
                     Type type = null;
                     if (array[i] is PropertyInfo)
                     {
                         type = ((PropertyInfo)array[i]).PropertyType;
                     }
                     else if (array[i] is FieldInfo)
                     {
                         type = ((FieldInfo)array[i]).FieldType;
                     }
                     WireType wireType2;
                     if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out wireType2, false, false, false, false) == null)
                     {
                         int num2 = this.FindOrAddAuto(type, false, false, false);
                         if (num2 >= 0)
                         {
                             metaType2 = ((MetaType)this.types[num2]).GetSurrogateOrBaseOrSelf(false);
                             if (!list.Contains(metaType2))
                             {
                                 list.Add(metaType2);
                                 this.CascadeDependents(list, metaType2);
                             }
                         }
                     }
                 }
             }
         }
         else
         {
             foreach (object obj in metaType.Fields)
             {
                 ValueMember valueMember = (ValueMember)obj;
                 Type        type2       = valueMember.ItemType;
                 if (type2 == null)
                 {
                     type2 = valueMember.MemberType;
                 }
                 WireType wireType3;
                 if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type2, out wireType3, false, false, false, false) == null)
                 {
                     int num3 = this.FindOrAddAuto(type2, false, false, false);
                     if (num3 >= 0)
                     {
                         metaType2 = ((MetaType)this.types[num3]).GetSurrogateOrBaseOrSelf(false);
                         if (!list.Contains(metaType2))
                         {
                             list.Add(metaType2);
                             this.CascadeDependents(list, metaType2);
                         }
                     }
                 }
             }
         }
         if (metaType.HasSubtypes)
         {
             SubType[] subtypes = metaType.GetSubtypes();
             for (int j = 0; j < subtypes.Length; j++)
             {
                 metaType2 = subtypes[j].DerivedType.GetSurrogateOrSelf();
                 if (!list.Contains(metaType2))
                 {
                     list.Add(metaType2);
                     this.CascadeDependents(list, metaType2);
                 }
             }
         }
         metaType2 = metaType.BaseType;
         if (metaType2 != null)
         {
             metaType2 = metaType2.GetSurrogateOrSelf();
         }
         if (metaType2 != null && !list.Contains(metaType2))
         {
             list.Add(metaType2);
             this.CascadeDependents(list, metaType2);
         }
     }
 }
        /// <summary>
        /// Fully compiles the current model into a static-compiled serialization dll
        /// (the serialization dll still requires protobuf-net for support services).
        /// </summary>
        /// <remarks>A full compilation is restricted to accessing public types / members</remarks>
        /// <param name="name">The name of the TypeModel class to create</param>
        /// <param name="path">The path for the new dll</param>
        /// <returns>An instance of the newly created compiled type-model</returns>
        public TypeModel Compile(string name, string path)
        {
            BuildAllSerializers();
            Freeze();
            bool save = !Helpers.IsNullOrEmpty(path);
            if (Helpers.IsNullOrEmpty(name))
            {
                if (save) throw new ArgumentNullException("name");
                name = Guid.NewGuid().ToString();
            }

            AssemblyName an = new AssemblyName();
            an.Name = name;
            AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(an,
                (save ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run)
                );

            ModuleBuilder module = save ? asm.DefineDynamicModule(name, path)
                : asm.DefineDynamicModule(name);
            Type baseType = typeof(TypeModel);
            TypeBuilder type = module.DefineType(name,
                (baseType.Attributes & ~TypeAttributes.Abstract) | TypeAttributes.Sealed,
                baseType);
            Compiler.CompilerContext ctx;
            
            int index = 0;
            bool hasInheritance = false;
            SerializerPair[] methodPairs = new SerializerPair[types.Count];
            foreach (MetaType metaType in types)
            {
                MethodBuilder writeMethod = type.DefineMethod("Write"
#if DEBUG
 + metaType.Type.Name
#endif
                    ,
                    MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard,
                    typeof(void), new Type[] { metaType.Type, typeof(ProtoWriter) });

                MethodBuilder readMethod = type.DefineMethod("Read"
#if DEBUG
 + metaType.Type.Name
#endif              
                    ,
                    MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard,
                    metaType.Type, new Type[] { metaType.Type, typeof(ProtoReader) });

                SerializerPair pair = new SerializerPair(
                    GetKey(metaType.Type, true, false), GetKey(metaType.Type, true, true), metaType,
                    writeMethod, readMethod, writeMethod.GetILGenerator(), readMethod.GetILGenerator());
                methodPairs[index++] = pair;
                if (pair.MetaKey != pair.BaseKey) hasInheritance = true;
            }
            if (hasInheritance)
            {
                Array.Sort(methodPairs);
            }
            
            for(index = 0; index < methodPairs.Length ; index++)
            {
                SerializerPair pair = methodPairs[index];
                ctx = new Compiler.CompilerContext(pair.SerializeBody, true, true, methodPairs);
                pair.Type.Serializer.EmitWrite(ctx, Compiler.Local.InputValue);
                ctx.Return();

                ctx = new Compiler.CompilerContext(pair.DeserializeBody, true, false, methodPairs);
                pair.Type.Serializer.EmitRead(ctx, Compiler.Local.InputValue);
                if (!pair.Type.Serializer.ReturnsValue)
                {
                    ctx.LoadValue(Compiler.Local.InputValue);
                }
                ctx.Return();
            }

            FieldBuilder knownTypes = type.DefineField("knownTypes", typeof(Type[]), FieldAttributes.Private | FieldAttributes.InitOnly);

            ILGenerator il = Override(type, "GetKeyImpl");
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, knownTypes);
            il.Emit(OpCodes.Ldarg_1);
            // note that Array.IndexOf is not supported under CF
            il.EmitCall(OpCodes.Callvirt,typeof(IList).GetMethod(
                "IndexOf", new Type[] { typeof(object) }), null);
            if (hasInheritance)
            {
                il.DeclareLocal(typeof(int)); // loc-0
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Stloc_0);

                BasicList getKeyLabels = new BasicList();
                int lastKey = -1;
                for (int i = 0; i < methodPairs.Length; i++)
                {
                    if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) break;
                    if (lastKey == methodPairs[i].BaseKey)
                    {   // add the last label again
                        getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]);
                    }
                    else
                    {   // add a new unique label
                        getKeyLabels.Add(il.DefineLabel());
                        lastKey = methodPairs[i].BaseKey;
                    }                    
                }
                Label[] subtypeLabels = new Label[getKeyLabels.Count];
                getKeyLabels.CopyTo(subtypeLabels, 0);

                il.Emit(OpCodes.Switch, subtypeLabels);
                il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value
                il.Emit(OpCodes.Ret);

                lastKey = -1;
                // now output the different branches per sub-type (not derived type)
                for (int i = subtypeLabels.Length - 1; i >= 0; i--)
                {
                    if (lastKey != methodPairs[i].BaseKey)
                    {
                        lastKey = methodPairs[i].BaseKey;
                        // find the actual base-index for this base-key (i.e. the index of
                        // the base-type)
                        int keyIndex = -1;
                        for (int j = subtypeLabels.Length; j < methodPairs.Length; j++)
                        {
                            if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                            {
                                keyIndex = j;
                                break;
                            }
                        }
                        il.MarkLabel(subtypeLabels[i]);
                        Compiler.CompilerContext.LoadValue(il, keyIndex);
                        il.Emit(OpCodes.Ret);
                    }
                }
            }
            else
            {
                il.Emit(OpCodes.Ret);
            }
            
            il = Override(type, "Serialize");
            ctx = new Compiler.CompilerContext(il, false, true, methodPairs);
            // arg0 = this, arg1 = key, arg2=obj, arg3=dest
            Label[] jumpTable = new Label[types.Count];
            for (int i = 0; i < jumpTable.Length; i++) {
                jumpTable[i] = il.DefineLabel();
            }
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Switch, jumpTable);
            ctx.Return();
            for (int i = 0; i < jumpTable.Length; i++)
            {
                SerializerPair pair = methodPairs[i];
                il.MarkLabel(jumpTable[i]);
                il.Emit(OpCodes.Ldarg_2);
                ctx.CastFromObject(pair.Type.Type);
                il.Emit(OpCodes.Ldarg_3);
                il.EmitCall(OpCodes.Call, pair.Serialize, null);
                ctx.Return();
            }

            il = Override(type, "Deserialize");
            ctx = new Compiler.CompilerContext(il, false, false, methodPairs);
            // arg0 = this, arg1 = key, arg2=obj, arg3=source
            for (int i = 0; i < jumpTable.Length; i++)
            {
                jumpTable[i] = il.DefineLabel();
            }
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Switch, jumpTable);
            ctx.LoadNullRef();
            ctx.Return();
            for (int i = 0; i < jumpTable.Length; i++)
            {
                SerializerPair pair = methodPairs[i];
                il.MarkLabel(jumpTable[i]);
                Type keyType = pair.Type.Type;
                if (keyType.IsValueType)
                {
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Ldarg_3);
                    il.EmitCall(OpCodes.Call, EmitBoxedSerializer(type, i, keyType, methodPairs), null);
                    ctx.Return();
                }
                else
                {
                    il.Emit(OpCodes.Ldarg_2);
                    ctx.CastFromObject(keyType);
                    il.Emit(OpCodes.Ldarg_3);
                    il.EmitCall(OpCodes.Call, pair.Deserialize, null);
                    ctx.Return();
                }
            }

            

            ConstructorBuilder ctor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Helpers.EmptyTypes);
            
            il = ctor.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, Helpers.GetConstructor(baseType, Helpers.EmptyTypes, true));
            il.Emit(OpCodes.Ldarg_0);
            Compiler.CompilerContext.LoadValue(il, types.Count);
            il.Emit(OpCodes.Newarr, typeof(Type));
            
            index = 0;
            foreach(SerializerPair pair in methodPairs)
            {
                il.Emit(OpCodes.Dup);
                Compiler.CompilerContext.LoadValue(il, index);
                il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
                il.Emit(OpCodes.Stelem_Ref);
                index++;
            }
            il.Emit(OpCodes.Stfld, knownTypes);            
            il.Emit(OpCodes.Ret);


            Type finalType = type.CreateType();
            if(!Helpers.IsNullOrEmpty(path))
            {
                asm.Save(path);
                Helpers.DebugWriteLine("Wrote dll:" + path);
            }

            return (TypeModel)Activator.CreateInstance(finalType);
        }
        public override object Read(object value, ProtoReader source)
        {
			if (nested)
			{
				source.ReadFieldHeader();
			}

            int field = source.FieldNumber;
            BasicList list = new BasicList();

			if (packedWireType != WireType.None && source.WireType == WireType.String)
            {
                SubItemToken token = ProtoReader.StartSubItem(source);
                while (ProtoReader.HasSubValue(packedWireType, source))
                {
                    list.Add(Tail.Read(null, source));
                }
                ProtoReader.EndSubItem(token, source);

				int oldLen = AppendToCollection ? ((value == null ? 0 : ((Array)value).Length)) : 0;
				Array result = Array.CreateInstance(itemType, oldLen + list.Count);
				if (oldLen != 0) ((Array)value).CopyTo(result, 0);
				list.CopyTo(result, oldLen);

            	return result;
            }
            else
            {
				bool readObject = true;
            	int arrayKey = 0;

				value = value ?? Array.CreateInstance(itemType, 0);

				if (AsReference)
            	{
					int objectKey = source.ReadInt32();

					if (objectKey > 0)
					{
						value = source.NetCache.GetKeyedObject(objectKey);
						readObject = false;
					}
					else
					{
						bool dummy;
						arrayKey = source.NetCache.AddObjectKey(value, out dummy);
					}
            	}
				else
				{
					bool isEmpty = source.ReadInt32() == 1;
					if (isEmpty)
					{
						return value; 
					}
				}

				if (readObject)
				{
					while (source.TryReadFieldHeader(field)) 
					{
						list.Add(Tail.Read(null, source));
					}

					Array newArray = Array.CreateInstance(itemType, list.Count);
					list.CopyTo(newArray, 0);

					if (AsReference)
					{
						source.NetCache.UpdateKeyedObject(arrayKey, value, newArray);	
					}

					value = newArray;
				}
            }

            return value;
        }
Example #22
0
        private static ProtoMemberAttribute NormalizeProtoMember(MemberInfo member, AttributeFamily family, bool forced, bool isEnum, BasicList partialMembers, int dataMemberOffset, bool inferByTagName)
        {
            if (member == null || (family == AttributeFamily.None && !isEnum))
            {
                return(null);                                                               // nix
            }
            int        fieldNumber = int.MinValue, minAcceptFieldNumber = inferByTagName ? -1 : 1;
            string     name = null;
            bool       isPacked = false, ignore = false, done = false, isRequired = false, asReference = false, dynamicType = false, tagIsPinned = false, overwriteList = false;
            DataFormat dataFormat = DataFormat.Default;

            if (isEnum)
            {
                forced = true;
            }
            object[]  attribs = member.GetCustomAttributes(true);
            Attribute attrib;

            if (isEnum)
            {
                attrib = GetAttribute(attribs, "ProtoBuf.ProtoIgnoreAttribute");
                if (attrib != null)
                {
                    ignore = true;
                }
                else
                {
                    attrib      = GetAttribute(attribs, "ProtoBuf.ProtoEnumAttribute");
                    fieldNumber = Convert.ToInt32(((FieldInfo)member).GetValue(null));
                    if (attrib != null)
                    {
                        GetFieldName(ref name, attrib, "Name");
                        if ((bool)attrib.GetType().GetMethod("HasValue").Invoke(attrib, null))
                        {
                            fieldNumber = (int)GetMemberValue(attrib, "Value");
                        }
                    }
                }
                done = true;
            }

            if (!ignore && !done) // always consider ProtoMember
            {
                attrib = GetAttribute(attribs, "ProtoBuf.ProtoMemberAttribute");
                GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.ProtoIgnoreAttribute");
                if (!ignore && attrib != null)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Tag");
                    GetFieldName(ref name, attrib, "Name");
                    GetFieldBoolean(ref isRequired, attrib, "IsRequired");
                    GetFieldBoolean(ref isPacked, attrib, "IsPacked");
                    GetFieldBoolean(ref overwriteList, attrib, "OverwriteList");
                    GetDataFormat(ref dataFormat, attrib, "DataFormat");
                    GetFieldBoolean(ref asReference, attrib, "AsReference");
                    GetFieldBoolean(ref dynamicType, attrib, "DynamicType");
                    done = tagIsPinned = fieldNumber > 0; // note minAcceptFieldNumber only applies to non-proto
                }

                if (!done && partialMembers != null)
                {
                    foreach (ProtoPartialMemberAttribute ppma in partialMembers)
                    {
                        if (ppma.MemberName == member.Name)
                        {
                            GetFieldNumber(ref fieldNumber, ppma, "Tag");
                            GetFieldName(ref name, ppma, "Name");
                            GetFieldBoolean(ref isRequired, ppma, "IsRequired");
                            GetFieldBoolean(ref isPacked, ppma, "IsPacked");
                            GetFieldBoolean(ref overwriteList, attrib, "OverwriteList");
                            GetDataFormat(ref dataFormat, ppma, "DataFormat");
                            GetFieldBoolean(ref asReference, ppma, "AsReference");
                            GetFieldBoolean(ref dynamicType, ppma, "DynamicType");
                            if (done = tagIsPinned = fieldNumber > 0)
                            {
                                break;                                       // note minAcceptFieldNumber only applies to non-proto
                            }
                        }
                    }
                }
            }

            if (!ignore && !done && HasFamily(family, AttributeFamily.DataContractSerialier))
            {
                attrib = GetAttribute(attribs, "System.Runtime.Serialization.DataMemberAttribute");
                if (attrib != null)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Order");
                    GetFieldName(ref name, attrib, "Name");
                    GetFieldBoolean(ref isRequired, attrib, "IsRequired");
                    done = fieldNumber >= minAcceptFieldNumber;
                    if (done)
                    {
                        fieldNumber += dataMemberOffset;       // dataMemberOffset only applies to DCS flags, to allow us to "bump" WCF by a notch
                    }
                }
            }
            if (!ignore && !done && HasFamily(family, AttributeFamily.XmlSerializer))
            {
                attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlElementAttribute");
                if (attrib == null)
                {
                    attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlArrayAttribute");
                }
                GetIgnore(ref ignore, attrib, attribs, "System.Xml.Serialization.XmlIgnoreAttribute");
                if (attrib != null && !ignore)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Order");
                    GetFieldName(ref name, attrib, "ElementName");
                    done = fieldNumber >= minAcceptFieldNumber;
                }
            }
            if (!ignore && !done)
            {
                if (GetAttribute(attribs, "System.NonSerializedAttribute") != null)
                {
                    ignore = true;
                }
            }
            if (ignore || (fieldNumber < minAcceptFieldNumber && !forced))
            {
                return(null);
            }
            ProtoMemberAttribute result = new ProtoMemberAttribute(fieldNumber, forced || inferByTagName);

            result.AsReference   = asReference;
            result.DataFormat    = dataFormat;
            result.DynamicType   = dynamicType;
            result.IsPacked      = isPacked;
            result.OverwriteList = overwriteList;
            result.IsRequired    = isRequired;
            result.Name          = Helpers.IsNullOrEmpty(name) ? member.Name : name;
            result.Member        = member;
            result.TagIsPinned   = tagIsPinned;
            return(result);
        }
Example #23
0
 bool InternalsVisible(Assembly assembly)
 {
     #if PHONE8 || SILVERLIGHT || FX11
     return false;
     #else
     if (Helpers.IsNullOrEmpty(assemblyName)) return false;
     if (knownTrustedAssemblies != null)
     {
         if (knownTrustedAssemblies.IndexOfReference(assembly) >= 0)
         {
             return true;
         }
     }
     if (knownUntrustedAssemblies != null)
     {
         if (knownUntrustedAssemblies.IndexOfReference(assembly) >= 0)
         {
             return false;
         }
     }
     bool isTrusted = false;
     Type attributeType = MapType(typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute));
     if(attributeType == null) return false;
     #if FEAT_IKVM
     foreach (CustomAttributeData attrib in assembly.__GetCustomAttributes(attributeType, false))
     {
         if (attrib.ConstructorArguments.Count == 1)
         {
             string privelegedAssembly = attrib.ConstructorArguments[0].Value as string;
             if (privelegedAssembly == assemblyName)
             {
                 isTrusted = true;
                 break;
             }
         }
     }
     #else
     foreach(System.Runtime.CompilerServices.InternalsVisibleToAttribute attrib in assembly.GetCustomAttributes(attributeType, false))
     {
         if (attrib.AssemblyName == assemblyName)
         {
             isTrusted = true;
             break;
         }
     }
     #endif
     if (isTrusted)
     {
         if (knownTrustedAssemblies == null) knownTrustedAssemblies = new BasicList();
         knownTrustedAssemblies.Add(assembly);
     }
     else
     {
         if (knownUntrustedAssemblies == null) knownUntrustedAssemblies = new BasicList();
         knownUntrustedAssemblies.Add(assembly);
     }
     return isTrusted;
     #endif
 }
Example #24
0
 // Token: 0x060032F1 RID: 13041 RVA: 0x001283C5 File Offset: 0x001267C5
 public Group(int first)
 {
     First = first;
     Items = new BasicList();
 }
    void ReadSInstance(ProtoReader reader, SInstance sInstance, CLS_Environment environment)
    {
        List<CLS_Content.Value> values;
        List<string> keywords;
        GetSortMembers(sInstance, out values, out keywords);

        int fieldNumber = 0;
        while ((fieldNumber = reader.ReadFieldHeader()) > 0)
        {
            Type memberT = values[fieldNumber - 1].type;
            CLS_Content.Value memberV = values[fieldNumber - 1];
            string sClassName = keywords[fieldNumber - 1];

            if (memberT == null)
            {
                memberT = typeof(SInstance);
                sClassName = ((SType)memberV.type).Name;
            }

            Type itemType = GetItemType(memberT);
            if (itemType != null)
            {
                sClassName = sInstance.type.members[sClassName].type.keyword;

                // 数组判断
                if (memberT.IsArray)
                {
                    string itemClass = sClassName.Substring(0, sClassName.Length - 2);  // 从 xxx[] 中提取xxx
                    BasicList list = new BasicList();
                    do
                    {
                        list.Add(ReadField(reader, itemType, itemClass, environment));
                    } while (reader.TryReadFieldHeader(fieldNumber));
                    Array result = Array.CreateInstance(itemType, list.Count);
                    list.CopyTo(result, 0);
                    memberV.value = result;
                }
                // 列表判断
                else
                {
                    string itemClass = sClassName.Substring(5, sClassName.Length - 6);  // 从 List<xxx> 中提取xxx
                    ICLS_Type iType = environment.GetTypeByKeywordQuiet(sClassName);
                    CLS_Content content = CLS_Content.NewContent(environment);
                    memberV.value = iType.function.New(content, m_emptyParams).value;
                    CLS_Content.PoolContent(content);
                    IList list = (IList)memberV.value;
                    do
                    {
                        list.Add(ReadField(reader, itemType, itemClass, environment));
                    } while (reader.TryReadFieldHeader(fieldNumber));
                }
            }
            else
            {
                memberV.value = ReadField(reader, memberT, sClassName, environment);
            }
        }
    }
Example #26
0
        private static ProtoMemberAttribute NormalizeProtoMember(MemberInfo member, AttributeFamily family, bool forced, bool isEnum, BasicList partialMembers, int dataMemberOffset, bool inferByTagName)
        {
            if (member == null || (family == AttributeFamily.None && !isEnum)) return null; // nix
            int fieldNumber = int.MinValue, minAcceptFieldNumber = inferByTagName ? -1 : 1;
            string name = null;
            bool isPacked = false, ignore = false, done = false, isRequired = false, asReference = false, dynamicType = false, tagIsPinned = false, overwriteList = false;
            DataFormat dataFormat = DataFormat.Default;
            if (isEnum) forced = true;
            object[] attribs = member.GetCustomAttributes(true);
            Attribute attrib;

            if (isEnum)
            {
                attrib = GetAttribute(attribs, "ProtoBuf.ProtoIgnoreAttribute");
                if (attrib != null)
                {
                    ignore = true;
                }
                else
                {
                    attrib = GetAttribute(attribs, "ProtoBuf.ProtoEnumAttribute");
                    fieldNumber = Convert.ToInt32(((FieldInfo)member).GetValue(null));
                    if (attrib != null)
                    {
                        GetFieldName(ref name, attrib, "Name");
                        if ((bool)attrib.GetType().GetMethod("HasValue").Invoke(attrib, null))
                        {
                            fieldNumber = (int)GetMemberValue(attrib, "Value");
                        }
                    }

                }
                done = true;
            }

            if (!ignore && !done) // always consider ProtoMember
            {
                attrib = GetAttribute(attribs, "ProtoBuf.ProtoMemberAttribute");
                GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.ProtoIgnoreAttribute");
                if (!ignore && attrib != null)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Tag");
                    GetFieldName(ref name, attrib, "Name");
                    GetFieldBoolean(ref isRequired, attrib, "IsRequired");
                    GetFieldBoolean(ref isPacked, attrib, "IsPacked");
                    GetFieldBoolean(ref overwriteList, attrib, "OverwriteList");
                    GetDataFormat(ref dataFormat, attrib, "DataFormat");
                    GetFieldBoolean(ref asReference, attrib, "AsReference");
                    GetFieldBoolean(ref dynamicType, attrib, "DynamicType");
                    done = tagIsPinned = fieldNumber > 0; // note minAcceptFieldNumber only applies to non-proto
                }

                if (!done && partialMembers != null)
                {
                    foreach (ProtoPartialMemberAttribute ppma in partialMembers)
                    {
                        if (ppma.MemberName == member.Name)
                        {
                            GetFieldNumber(ref fieldNumber, ppma, "Tag");
                            GetFieldName(ref name, ppma, "Name");
                            GetFieldBoolean(ref isRequired, ppma, "IsRequired");
                            GetFieldBoolean(ref isPacked, ppma, "IsPacked");
                            GetFieldBoolean(ref overwriteList, attrib, "OverwriteList");
                            GetDataFormat(ref dataFormat, ppma, "DataFormat");
                            GetFieldBoolean(ref asReference, ppma, "AsReference");
                            GetFieldBoolean(ref dynamicType, ppma, "DynamicType");
                            if (done = tagIsPinned = fieldNumber > 0) break; // note minAcceptFieldNumber only applies to non-proto
                        }
                    }
                }
            }

            if (!ignore && !done && HasFamily(family, AttributeFamily.DataContractSerialier))
            {
                attrib = GetAttribute(attribs, "System.Runtime.Serialization.DataMemberAttribute");
                if (attrib != null)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Order");
                    GetFieldName(ref name, attrib, "Name");
                    GetFieldBoolean(ref isRequired, attrib, "IsRequired");
                    done = fieldNumber >= minAcceptFieldNumber;
                    if (done) fieldNumber += dataMemberOffset; // dataMemberOffset only applies to DCS flags, to allow us to "bump" WCF by a notch
                }
            }
            if (!ignore && !done && HasFamily(family, AttributeFamily.XmlSerializer))
            {
                attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlElementAttribute");
                if(attrib == null) attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlArrayAttribute");
                GetIgnore(ref ignore, attrib, attribs, "System.Xml.Serialization.XmlIgnoreAttribute");
                if (attrib != null && !ignore)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Order");
                    GetFieldName(ref name, attrib, "ElementName");
                    done = fieldNumber >= minAcceptFieldNumber;
                }
            }
            if (!ignore && !done)
            {
                if (GetAttribute(attribs, "System.NonSerializedAttribute") != null) ignore = true;
            }
            if (ignore || (fieldNumber < minAcceptFieldNumber && !forced)) return null;
            ProtoMemberAttribute result = new ProtoMemberAttribute(fieldNumber, forced || inferByTagName);
            result.AsReference = asReference;
            result.DataFormat = dataFormat;
            result.DynamicType = dynamicType;
            result.IsPacked = isPacked;
            result.OverwriteList = overwriteList;
            result.IsRequired = isRequired;
            result.Name = Helpers.IsNullOrEmpty(name) ? member.Name : name;
            result.Member = member;
            result.TagIsPinned = tagIsPinned;
            return result;
        }
Example #27
0
        internal void ApplyDefaultBehaviour()
        {
            if (type.BaseType != null && model.FindWithoutAdd(type.BaseType) == null
                && GetContractFamily(type.BaseType, null) != MetaType.AttributeFamily.None)
            {
                model.FindOrAddAuto(type.BaseType, true, false, false);
            }

            object[] typeAttribs = type.GetCustomAttributes(true);
            AttributeFamily family = GetContractFamily(type, typeAttribs);
            bool isEnum = type.IsEnum;
            if(family ==  AttributeFamily.None && !isEnum) return; // and you'd like me to do what, exactly?
            BasicList partialIgnores = null, partialMembers = null;
            int dataMemberOffset = 0, implicitFirstTag = 1;
            bool inferTagByName = model.InferTagFromNameDefault;
            ImplicitFields implicitMode = ImplicitFields.None;

            for (int i = 0; i < typeAttribs.Length; i++)
            {
                Attribute item = (Attribute)typeAttribs[i];
                if (!isEnum && item is ProtoIncludeAttribute)
                {
                    ProtoIncludeAttribute pia = (ProtoIncludeAttribute)item;
                    Type knownType = pia.ResolveKnownType(type.Assembly);
                    if (knownType == null)
                    {
                        throw new InvalidOperationException("Unable to resolve sub-type: " + pia.KnownTypeName);
                    }
                    AddSubType(pia.Tag, knownType);
                }
                if(item is ProtoPartialIgnoreAttribute)
                {
                    if(partialIgnores == null) partialIgnores = new BasicList();
                    partialIgnores.Add(((ProtoPartialIgnoreAttribute)item).MemberName);
                }
                if (!isEnum && item is ProtoPartialMemberAttribute)
                {
                    if (partialMembers == null) partialMembers = new BasicList();
                    partialMembers.Add(item);
                }
                if (!isEnum && item is ProtoContractAttribute)
                {
                    ProtoContractAttribute pca = (ProtoContractAttribute)item;
                    dataMemberOffset = pca.DataMemberOffset;
                    if (pca.InferTagFromNameHasValue) inferTagByName = pca.InferTagFromName;
                    implicitMode = pca.ImplicitFields;
                    UseConstructor = !pca.SkipConstructor;
                    if(pca.ImplicitFirstTag > 0) implicitFirstTag = pca.ImplicitFirstTag;
                }
            }
            if (implicitMode != ImplicitFields.None)
            {
                family &= AttributeFamily.ProtoBuf; // with implicit fields, **only** proto attributes are important
            }
            MethodInfo[] callbacks = null;

            BasicList members = new BasicList();

            foreach (MemberInfo member in type.GetMembers(isEnum ? BindingFlags.Public | BindingFlags.Static
                : BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (member.DeclaringType != type) continue;
                if (member.IsDefined(typeof(ProtoIgnoreAttribute), true)) continue;
                if (partialIgnores != null && partialIgnores.Contains(member.Name)) continue;

                bool forced = false, isPublic, isField;
                Type effectiveType;
                switch (member.MemberType)
                {
                    case MemberTypes.Property:
                        PropertyInfo property = (PropertyInfo)member;
                        effectiveType = property.PropertyType;
                        isPublic = property.GetGetMethod(false) != null;
                        isField = false;
                        goto ProcessMember;
                    case MemberTypes.Field:
                        FieldInfo field = (FieldInfo)member;
                        effectiveType = field.FieldType;
                        isPublic = field.IsPublic;
                        isField = true;
                    ProcessMember:
                        switch(implicitMode)
                        {
                            case ImplicitFields.AllFields:
                                if (isField) forced = true;
                                break;
                            case ImplicitFields.AllPublic:
                                if (isPublic) forced = true;
                                break;
                        }
                        if (effectiveType.IsSubclassOf(typeof(Delegate))) continue; // we just don't like delegate types ;p
                        ProtoMemberAttribute normalizedAttribute = NormalizeProtoMember(member, family, forced, isEnum, partialMembers, dataMemberOffset, inferTagByName);
                        if(normalizedAttribute != null) members.Add(normalizedAttribute);
                        break;
                    case MemberTypes.Method:
                        if (isEnum) continue;
                        MethodInfo method = (MethodInfo)member;
                        object[] memberAttribs = Attribute.GetCustomAttributes(method);
                        if (memberAttribs != null && memberAttribs.Length > 0)
                        {
                            CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeSerializationAttribute", ref callbacks, 0);
                            CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterSerializationAttribute", ref callbacks, 1);
                            CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeDeserializationAttribute", ref callbacks, 2);
                            CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterDeserializationAttribute", ref callbacks, 3);
                            CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializingAttribute", ref callbacks, 4);
                            CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializedAttribute", ref callbacks, 5);
                            CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializingAttribute", ref callbacks, 6);
                            CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializedAttribute", ref callbacks, 7);
                        }
                        break;
                }
            }
            ProtoMemberAttribute[] arr = new ProtoMemberAttribute[members.Count];
            members.CopyTo(arr, 0);

            if (inferTagByName || implicitMode != ImplicitFields.None)
            {
                Array.Sort(arr);
                int nextTag = implicitFirstTag;
                foreach (ProtoMemberAttribute normalizedAttribute in arr)
                {
                    if (!normalizedAttribute.TagIsPinned) // if ProtoMember etc sets a tag, we'll trust it
                    {
                        normalizedAttribute.Rebase(nextTag++);
                    }
                }
            }

            foreach (ProtoMemberAttribute normalizedAttribute in arr)
            {
                ValueMember vm = ApplyDefaultBehaviour(isEnum, normalizedAttribute);
                if (vm != null)
                {
                    Add(vm);
                }
            }

            if (callbacks != null)
            {
                SetCallbacks(Coalesce(callbacks, 0, 4), Coalesce(callbacks, 1, 5),
                    Coalesce(callbacks, 2, 6), Coalesce(callbacks, 3, 7));
            }
        }
Example #28
0
        private IProtoTypeSerializer BuildSerializer()
        {
            if (type.IsEnum)
            {
                //return new TagDecorator(ProtoBuf.Serializer.ListItemTag, WireType.Variant, false, new EnumSerializer(type, GetEnumMap()));
                return new TypeSerializer(type, new int[] { ProtoBuf.Serializer.ListItemTag },
                    new IProtoSerializer[] {
                        new TagDecorator(ProtoBuf.Serializer.ListItemTag, WireType.Variant, false, new EnumSerializer(type, GetEnumMap()))
                    }, null, true, true, null, constructType);
            }
            if (surrogate != null)
            {
                MetaType mt = model[surrogate], mtBase;
                while ((mtBase = mt.baseType) != null) { mt = mtBase; }
                return new SurrogateSerializer(type, surrogate, mt.Serializer);
            }

            Type itemType = TypeModel.GetListItemType(type);
            if (itemType != null)
            {
                ValueMember fakeMember = new ValueMember(model, ProtoBuf.Serializer.ListItemTag, type, itemType, type, DataFormat.Default);
                return new TypeSerializer(type, new int[] { ProtoBuf.Serializer.ListItemTag }, new IProtoSerializer[] { fakeMember.Serializer }, null, true, true, null, constructType);
            }

            fields.Trim();
            int fieldCount = fields.Count;
            int subTypeCount = subTypes == null ? 0 : subTypes.Count;
            int[] fieldNumbers = new int[fieldCount + subTypeCount];
            IProtoSerializer[] serializers = new IProtoSerializer[fieldCount + subTypeCount];
            int i = 0;
            if (subTypeCount != 0)
            {
                foreach (SubType subType in subTypes)
                {
                    fieldNumbers[i] = subType.FieldNumber;
                    serializers[i++] = subType.Serializer;
                }
            }
            if (fieldCount != 0)
            {
                foreach (ValueMember member in fields)
                {
                    fieldNumbers[i] = member.FieldNumber;
                    serializers[i++] = member.Serializer;
                }
            }

            BasicList baseCtorCallbacks = null;
            MetaType tmp = BaseType;

            while (tmp != null)
            {
                MethodInfo method = tmp.HasCallbacks ? tmp.Callbacks.BeforeDeserialize : null;
                if (method != null)
                {
                    if (baseCtorCallbacks == null) baseCtorCallbacks = new BasicList();
                    baseCtorCallbacks.Add(method);
                }
                tmp = tmp.BaseType;
            }
            MethodInfo[] arr = null;
            if (baseCtorCallbacks != null)
            {
                arr = new MethodInfo[baseCtorCallbacks.Count];
                baseCtorCallbacks.CopyTo(arr, 0);
                Array.Reverse(arr);
            }
            return new TypeSerializer(type, fieldNumbers, serializers, arr, baseType == null, UseConstructor, callbacks, constructType);
        }
Example #29
0
        private bool TryDeserializeList(TypeModel model, ProtoReader reader, DataFormat format, int tag, Type listType, Type itemType, ref object value)
        {
            bool       isList;
            MethodInfo methodInfo = ResolveListAdd(model, listType, itemType, out isList);

            if (methodInfo == null)
            {
                throw new NotSupportedException("Unknown list variant: " + listType.FullName);
            }
            bool   result = false;
            object value2 = null;
            IList  list   = value as IList;

            object[]  array     = isList ? null : new object[1];
            BasicList basicList = listType.IsArray ? new BasicList() : null;

            while (TryDeserializeAuxiliaryType(reader, format, tag, itemType, ref value2, skipOtherFields: true, asListItem: true, autoCreate: true, insideList: true))
            {
                result = true;
                if (value == null && basicList == null)
                {
                    value = CreateListInstance(listType, itemType);
                    list  = (value as IList);
                }
                if (list != null)
                {
                    list.Add(value2);
                }
                else if (basicList != null)
                {
                    basicList.Add(value2);
                }
                else
                {
                    array[0] = value2;
                    methodInfo.Invoke(value, array);
                }
                value2 = null;
            }
            if (basicList != null)
            {
                if (value != null)
                {
                    if (basicList.Count != 0)
                    {
                        Array array2 = (Array)value;
                        Array array3 = Array.CreateInstance(itemType, array2.Length + basicList.Count);
                        Array.Copy(array2, array3, array2.Length);
                        basicList.CopyTo(array3, array2.Length);
                        value = array3;
                    }
                }
                else
                {
                    Array array3 = Array.CreateInstance(itemType, basicList.Count);
                    basicList.CopyTo(array3, 0);
                    value = array3;
                }
            }
            return(result);
        }
Example #30
0
        internal static Type GetListItemType(TypeModel model, Type listType)
        {
            if (listType == model.MapType(typeof(string)) || listType.IsArray || !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType))
            {
                return(null);
            }
            BasicList basicList = new BasicList();

            MethodInfo[] methods = listType.GetMethods();
            foreach (MethodInfo methodInfo in methods)
            {
                if (!methodInfo.IsStatic && !(methodInfo.Name != "Add"))
                {
                    ParameterInfo[] parameters = methodInfo.GetParameters();
                    Type            parameterType;
                    if (parameters.Length == 1 && !basicList.Contains(parameterType = parameters[0].ParameterType))
                    {
                        basicList.Add(parameterType);
                    }
                }
            }
            string name = listType.Name;

            if (name == null || (name.IndexOf("Queue") < 0 && name.IndexOf("Stack") < 0))
            {
                TestEnumerableListPatterns(model, basicList, listType);
                Type[] interfaces = listType.GetInterfaces();
                foreach (Type iType in interfaces)
                {
                    TestEnumerableListPatterns(model, basicList, iType);
                }
            }
            PropertyInfo[] properties = listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (PropertyInfo propertyInfo in properties)
            {
                if (!(propertyInfo.Name != "Item") && !basicList.Contains(propertyInfo.PropertyType))
                {
                    ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters();
                    if (indexParameters.Length == 1 && indexParameters[0].ParameterType == model.MapType(typeof(int)))
                    {
                        basicList.Add(propertyInfo.PropertyType);
                    }
                }
            }
            switch (basicList.Count)
            {
            case 0:
                return(null);

            case 1:
                return((Type)basicList[0]);

            case 2:
                if (CheckDictionaryAccessors(model, (Type)basicList[0], (Type)basicList[1]))
                {
                    return((Type)basicList[0]);
                }
                if (CheckDictionaryAccessors(model, (Type)basicList[1], (Type)basicList[0]))
                {
                    return((Type)basicList[1]);
                }
                break;
            }
            return(null);
        }
        private void WriteGetKeyImpl(TypeBuilder type, bool hasInheritance, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName, out ILGenerator il, out int knownTypesCategory, out FieldBuilder knownTypes, out Type knownTypesLookupType)
        {

            il = Override(type, "GetKeyImpl");
            Compiler.CompilerContext ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(System.Type), true));
            
            if (types.Count <= KnownTypes_ArrayCutoff)
            {
                knownTypesCategory = KnownTypes_Array;
                knownTypesLookupType = MapType(typeof(System.Type[]), true);
            }
            else
            {
#if NO_GENERICS
                knownTypesLookupType = null;
#else
                knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary<System.Type, int>), false);
#endif
                if (knownTypesLookupType == null)
                {
                    knownTypesLookupType = MapType(typeof(Hashtable), true);
                    knownTypesCategory = KnownTypes_Hashtable;
                }
                else
                {
                    knownTypesCategory = KnownTypes_Dictionary;
                }
            }
            knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static);

            switch (knownTypesCategory)
            {
                case KnownTypes_Array:
                    {
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        // note that Array.IndexOf is not supported under CF
                        il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod(
                            "IndexOf", new Type[] { MapType(typeof(object)) }), null);
                        if (hasInheritance)
                        {
                            il.DeclareLocal(MapType(typeof(int))); // loc-0
                            il.Emit(OpCodes.Dup);
                            il.Emit(OpCodes.Stloc_0);

                            BasicList getKeyLabels = new BasicList();
                            int lastKey = -1;
                            for (int i = 0; i < methodPairs.Length; i++)
                            {
                                if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) break;
                                if (lastKey == methodPairs[i].BaseKey)
                                {   // add the last label again
                                    getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]);
                                }
                                else
                                {   // add a new unique label
                                    getKeyLabels.Add(ctx.DefineLabel());
                                    lastKey = methodPairs[i].BaseKey;
                                }
                            }
                            Compiler.CodeLabel[] subtypeLabels = new Compiler.CodeLabel[getKeyLabels.Count];
                            getKeyLabels.CopyTo(subtypeLabels, 0);

                            ctx.Switch(subtypeLabels);
                            il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value
                            il.Emit(OpCodes.Ret);

                            lastKey = -1;
                            // now output the different branches per sub-type (not derived type)
                            for (int i = subtypeLabels.Length - 1; i >= 0; i--)
                            {
                                if (lastKey != methodPairs[i].BaseKey)
                                {
                                    lastKey = methodPairs[i].BaseKey;
                                    // find the actual base-index for this base-key (i.e. the index of
                                    // the base-type)
                                    int keyIndex = -1;
                                    for (int j = subtypeLabels.Length; j < methodPairs.Length; j++)
                                    {
                                        if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                                        {
                                            keyIndex = j;
                                            break;
                                        }
                                    }
                                    ctx.MarkLabel(subtypeLabels[i]);
                                    Compiler.CompilerContext.LoadValue(il, keyIndex);
                                    il.Emit(OpCodes.Ret);
                                }
                            }
                        }
                        else
                        {
                            il.Emit(OpCodes.Ret);
                        }
                    }
                    break;
                case KnownTypes_Dictionary:
                    {
                        LocalBuilder result = il.DeclareLocal(MapType(typeof(int)));
                        Label otherwise = il.DefineLabel();
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Ldloca_S, result);
                        il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null);
                        il.Emit(OpCodes.Brfalse_S, otherwise);
                        il.Emit(OpCodes.Ldloc_S, result);
                        il.Emit(OpCodes.Ret);
                        il.MarkLabel(otherwise);
                        il.Emit(OpCodes.Ldc_I4_M1);
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                case KnownTypes_Hashtable:
                    {
                        Label otherwise = il.DefineLabel();
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null);
                        il.Emit(OpCodes.Dup);
                        il.Emit(OpCodes.Brfalse_S, otherwise);
#if FX11
                        il.Emit(OpCodes.Unbox, MapType(typeof(int)));
                        il.Emit(OpCodes.Ldobj, MapType(typeof(int)));
#else
                        if (ilVersion == Compiler.CompilerContext.ILVersion.Net1)
                        {
                            il.Emit(OpCodes.Unbox, MapType(typeof(int)));
                            il.Emit(OpCodes.Ldobj, MapType(typeof(int)));
                        }
                        else
                        {
                            il.Emit(OpCodes.Unbox_Any, MapType(typeof(int)));
                        }
#endif
                        il.Emit(OpCodes.Ret);
                        il.MarkLabel(otherwise);
                        il.Emit(OpCodes.Pop);
                        il.Emit(OpCodes.Ldc_I4_M1);
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                default:
                    throw new InvalidOperationException();
            }
        }
        private void WriteAssemblyAttributes(CompilerOptions options, string assemblyName, AssemblyBuilder asm)
        {
            if (!Helpers.IsNullOrEmpty(options.TargetFrameworkName))
            {
                // get [TargetFramework] from mscorlib/equivalent and burn into the new assembly
                Type versionAttribType = null;
                try
                { // this is best-endeavours only
                    versionAttribType = GetType("System.Runtime.Versioning.TargetFrameworkAttribute", MapType(typeof(string)).Assembly);
                }
                catch { /* don't stress */ }
                if (versionAttribType != null)
                {
                    PropertyInfo[] props;
                    object[] propValues;
                    if (Helpers.IsNullOrEmpty(options.TargetFrameworkDisplayName))
                    {
                        props = new PropertyInfo[0];
                        propValues = new object[0];
                    }
                    else
                    {
                        props = new PropertyInfo[1] { versionAttribType.GetProperty("FrameworkDisplayName") };
                        propValues = new object[1] { options.TargetFrameworkDisplayName };
                    }
                    CustomAttributeBuilder builder = new CustomAttributeBuilder(
                        versionAttribType.GetConstructor(new Type[] { MapType(typeof(string)) }),
                        new object[] { options.TargetFrameworkName },
                        props,
                        propValues);
                    asm.SetCustomAttribute(builder);
                }
            }

            // copy assembly:InternalsVisibleTo
            Type internalsVisibleToAttribType = null;
#if !FX11
            try
            {
                internalsVisibleToAttribType = MapType(typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute));
            }
            catch { /* best endeavors only */ }
#endif
            if (internalsVisibleToAttribType != null)
            {
                BasicList internalAssemblies = new BasicList(), consideredAssemblies = new BasicList();
                foreach (MetaType metaType in types)
                {
                    Assembly assembly = metaType.Type.Assembly;
                    if (consideredAssemblies.IndexOfReference(assembly) >= 0) continue;
                    consideredAssemblies.Add(assembly);

                    AttributeMap[] assemblyAttribsMap = AttributeMap.Create(this, assembly);
                    for (int i = 0; i < assemblyAttribsMap.Length; i++)
                    {

                        if (assemblyAttribsMap[i].AttributeType != internalsVisibleToAttribType) continue;

                        object privelegedAssemblyObj;
                        assemblyAttribsMap[i].TryGet("AssemblyName", out privelegedAssemblyObj);
                        string privelegedAssemblyName = privelegedAssemblyObj as string;
                        if (privelegedAssemblyName == assemblyName || Helpers.IsNullOrEmpty(privelegedAssemblyName)) continue; // ignore

                        if (internalAssemblies.IndexOfString(privelegedAssemblyName) >= 0) continue; // seen it before
                        internalAssemblies.Add(privelegedAssemblyName);

                        CustomAttributeBuilder builder = new CustomAttributeBuilder(
                            internalsVisibleToAttribType.GetConstructor(new Type[] { MapType(typeof(string)) }),
                            new object[] { privelegedAssemblyName });
                        asm.SetCustomAttribute(builder);
                    }
                }
            }
        }
        private IProtoTypeSerializer BuildSerializer()
        {
            if (surrogate != null) return new SurrogateSerializer(type, model[surrogate].Serializer);

            fields.Trim();
            int fieldCount = fields.Count;
            int subTypeCount = subTypes == null ? 0 : subTypes.Count;
            int[] fieldNumbers = new int[fieldCount + subTypeCount];
            IProtoSerializer[] serializers = new IProtoSerializer[fieldCount + subTypeCount];
            int i = 0;
            if (subTypeCount != 0)
            {
                foreach (SubType subType in subTypes)
                {
                    fieldNumbers[i] = subType.FieldNumber;
                    serializers[i++] = subType.Serializer;
                }
            }
            if (fieldCount != 0)
            {
                foreach (ValueMember member in fields)
                {
                    fieldNumbers[i] = member.FieldNumber;
                    serializers[i++] = member.Serializer;
                }
            }

            BasicList baseCtorCallbacks = null;
            MetaType tmp = BaseType;
            while (tmp != null)
            {
                MethodInfo method = tmp.HasCallbacks ? tmp.Callbacks.BeforeDeserialize : null;
                if (method != null)
                {
                    if (baseCtorCallbacks == null) baseCtorCallbacks = new BasicList();
                    baseCtorCallbacks.Add(method);
                }
                tmp = tmp.BaseType;
            }
            MethodInfo[] arr = null;
            if (baseCtorCallbacks != null)
            {
                arr = new MethodInfo[baseCtorCallbacks.Count];
                baseCtorCallbacks.CopyTo(arr, 0);
                Array.Reverse(arr);
            }
            return new TypeSerializer(type, fieldNumbers, serializers, arr, baseType == null, useConstructor, callbacks);
        }
Example #34
0
 internal static BasicList GetContiguousGroups(int[] keys, object[] values)
 {
     if (keys == null) throw new ArgumentNullException("keys");
     if (values == null) throw new ArgumentNullException("values");
     if (values.Length < keys.Length) throw new ArgumentException("Not all keys are covered by values", "values");
     BasicList outer = new BasicList();
     Group group = null;
     for (int i = 0; i < keys.Length; i++)
     {
         if (i == 0 || keys[i] != keys[i - 1]) { group = null; }
         if (group == null)
         {
             group = new Group(keys[i]);
             outer.Add(group);
         }
         group.Items.Add(values[i]);
     }
     return outer;
 }
        internal void ApplyDefaultBehaviour()
        {
            if (model.FindWithoutAdd(type.BaseType) == null
                && GetContractFamily(type.BaseType, null) != MetaType.AttributeFamily.None)
            {
                model.FindOrAddAuto(type.BaseType, true, false, false);
            }

            object[] typeAttribs = type.GetCustomAttributes(true);
            AttributeFamily family = GetContractFamily(type, typeAttribs);
            bool isEnum = type.IsEnum;
            if(family ==  AttributeFamily.None && !isEnum) return; // and you'd like me to do what, exactly?
            BasicList partialIgnores = null, partialMembers = null;
            for (int i = 0; i < typeAttribs.Length; i++)
            {
                if (!isEnum && typeAttribs[i] is ProtoIncludeAttribute)
                {
                    ProtoIncludeAttribute pia = (ProtoIncludeAttribute)typeAttribs[i];
                    AddSubType(pia.Tag, pia.KnownType);
                }
                if(typeAttribs[i] is ProtoPartialIgnoreAttribute)
                {
                    if(partialIgnores == null) partialIgnores = new BasicList();
                    partialIgnores.Add(((ProtoPartialIgnoreAttribute)typeAttribs[i]).MemberName);
                }
                if (!isEnum && typeAttribs[i] is ProtoPartialMemberAttribute)
                {
                    if (partialMembers == null) partialMembers = new BasicList();
                    partialMembers.Add(typeAttribs[i]);
                }
            }
            MethodInfo[] callbacks = null;
            foreach (MemberInfo member in type.GetMembers(isEnum ? BindingFlags.Public | BindingFlags.Static
                : BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (member.DeclaringType != type) continue;
                if (member.IsDefined(typeof(ProtoIgnoreAttribute), true)) continue;
                if (partialIgnores != null && partialIgnores.Contains(member.Name)) continue;

                switch (member.MemberType)
                {
                    case MemberTypes.Property:
                    case MemberTypes.Field:
                        ValueMember vm = ApplyDefaultBehaviour(isEnum, family, member, partialMembers);
                        if (vm != null)
                        {
                            Add(vm);
                        }
                        break;
                    case MemberTypes.Method:
                        if (isEnum) continue;
                        MethodInfo method = (MethodInfo)member;
                        object[] memberAttribs = Attribute.GetCustomAttributes(method);
                        if (memberAttribs != null && memberAttribs.Length > 0)
                        {
                            CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeSerializationAttribute", ref callbacks, 0);
                            CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterSerializationAttribute", ref callbacks, 1);
                            CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeDeserializationAttribute", ref callbacks, 2);
                            CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterDeserializationAttribute", ref callbacks, 3);
                            CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializingAttribute", ref callbacks, 4);
                            CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializedAttribute", ref callbacks, 5);
                            CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializingAttribute", ref callbacks, 6);
                            CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializedAttribute", ref callbacks, 7);
                        }
                        break;
                }
            }
            if (callbacks != null)
            {
                SetCallbacks(callbacks[0] ?? callbacks[4], callbacks[1] ?? callbacks[5],
                    callbacks[2] ?? callbacks[6], callbacks[3] ?? callbacks[7]);
            }
        }
Example #36
0
 private void CascadeDependents(BasicList list, MetaType metaType)
 {
     if (metaType.IsList)
     {
         Type listItemType = TypeModel.GetListItemType(this, metaType.Type);
         WireType wireType;
         if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, listItemType, out wireType, false, false, false, false) == null)
         {
             int num = this.FindOrAddAuto(listItemType, false, false, false);
             if (num >= 0)
             {
                 MetaType metaType2 = ((MetaType)this.types[num]).GetSurrogateOrBaseOrSelf(false);
                 if (!list.Contains(metaType2))
                 {
                     list.Add(metaType2);
                     this.CascadeDependents(list, metaType2);
                 }
             }
         }
     }
     else
     {
         MetaType metaType2;
         if (metaType.IsAutoTuple)
         {
             MemberInfo[] array;
             if (MetaType.ResolveTupleConstructor(metaType.Type, out array) != null)
             {
                 for (int i = 0; i < array.Length; i++)
                 {
                     Type type = null;
                     if (array[i] is PropertyInfo)
                     {
                         type = ((PropertyInfo)array[i]).PropertyType;
                     }
                     else if (array[i] is FieldInfo)
                     {
                         type = ((FieldInfo)array[i]).FieldType;
                     }
                     WireType wireType2;
                     if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out wireType2, false, false, false, false) == null)
                     {
                         int num2 = this.FindOrAddAuto(type, false, false, false);
                         if (num2 >= 0)
                         {
                             metaType2 = ((MetaType)this.types[num2]).GetSurrogateOrBaseOrSelf(false);
                             if (!list.Contains(metaType2))
                             {
                                 list.Add(metaType2);
                                 this.CascadeDependents(list, metaType2);
                             }
                         }
                     }
                 }
             }
         }
         else
         {
             foreach (ValueMember valueMember in metaType.Fields)
             {
                 Type type2 = valueMember.ItemType;
                 if (type2 == null)
                 {
                     type2 = valueMember.MemberType;
                 }
                 WireType wireType3;
                 if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type2, out wireType3, false, false, false, false) == null)
                 {
                     int num3 = this.FindOrAddAuto(type2, false, false, false);
                     if (num3 >= 0)
                     {
                         metaType2 = ((MetaType)this.types[num3]).GetSurrogateOrBaseOrSelf(false);
                         if (!list.Contains(metaType2))
                         {
                             list.Add(metaType2);
                             this.CascadeDependents(list, metaType2);
                         }
                     }
                 }
             }
         }
         if (metaType.HasSubtypes)
         {
             SubType[] subtypes = metaType.GetSubtypes();
             for (int j = 0; j < subtypes.Length; j++)
             {
                 SubType subType = subtypes[j];
                 metaType2 = subType.DerivedType.GetSurrogateOrSelf();
                 if (!list.Contains(metaType2))
                 {
                     list.Add(metaType2);
                     this.CascadeDependents(list, metaType2);
                 }
             }
         }
         metaType2 = metaType.BaseType;
         if (metaType2 != null)
         {
             metaType2 = metaType2.GetSurrogateOrSelf();
         }
         if (metaType2 != null && !list.Contains(metaType2))
         {
             list.Add(metaType2);
             this.CascadeDependents(list, metaType2);
         }
     }
 }
        private ValueMember ApplyDefaultBehaviour(bool isEnum, AttributeFamily family, MemberInfo member, BasicList partialMembers)
        {
            if (member == null || (family == AttributeFamily.None && !isEnum)) return null; // nix
            Type effectiveType;
            switch (member.MemberType)
            {
                case MemberTypes.Field:
                    effectiveType = ((FieldInfo)member).FieldType; break;
                case MemberTypes.Property:
                    effectiveType = ((PropertyInfo)member).PropertyType; break;
                default:
                    return null; // nothing doing
            }

            int fieldNumber = 0;
            bool isPacked = false;
            string name = null;
            bool isRequired = false;
            Type itemType = null;
            Type defaultType = null;
            ResolveListTypes(effectiveType, ref itemType, ref defaultType);
            object[] attribs = member.GetCustomAttributes(true);
            Attribute attrib;
            DataFormat dataFormat = DataFormat.Default;
            bool ignore = false;
            object defaultValue = null;
            // implicit zero default
            switch (Type.GetTypeCode(effectiveType))
            {
                case TypeCode.Boolean: defaultValue = false; break;
                case TypeCode.Decimal: defaultValue = (decimal)0; break;
                case TypeCode.Single: defaultValue = (float)0; break;
                case TypeCode.Double: defaultValue = (double)0; break;
                case TypeCode.Byte: defaultValue = (byte)0;  break;
                case TypeCode.Char: defaultValue = (char)0; break;
                case TypeCode.Int16: defaultValue = (short)0; break;
                case TypeCode.Int32: defaultValue = (int)0; break;
                case TypeCode.Int64: defaultValue = (long)0; break;
                case TypeCode.SByte: defaultValue = (sbyte)0; break;
                case TypeCode.UInt16: defaultValue = (ushort)0; break;
                case TypeCode.UInt32: defaultValue = (uint)0; break;
                case TypeCode.UInt64: defaultValue = (ulong)0; break;
                default:
                    if (effectiveType == typeof(TimeSpan)) defaultValue = TimeSpan.Zero;
                    if (effectiveType == typeof(Guid)) defaultValue = Guid.Empty;
                    break;
            }
            bool done = false;
            if (isEnum)
            {
                attrib = GetAttribute(attribs, "ProtoBuf.ProtoIgnoreAttribute");
                if (attrib != null)
                {
                    ignore = true;
                }
                else
                {
                    attrib = GetAttribute(attribs, "ProtoBuf.ProtoEnumAttribute");
                    fieldNumber = Convert.ToInt32(((FieldInfo)member).GetValue(null));
                    if (attrib != null)
                    {
                        GetFieldName(ref name, attrib, "Name");
                        if ((bool)attrib.GetType().GetMethod("HasValue").Invoke(attrib, null))
                        {
                            fieldNumber = (int) GetMemberValue(attrib, "Value");
                        }
                    }
                        
                }
                done = true;
            }
            if (!ignore && !done) // always consider ProtoMember 
            {
                attrib = GetAttribute(attribs, "ProtoBuf.ProtoMemberAttribute");
                GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.ProtoIgnoreAttribute");
                if (!ignore)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Tag");
                    GetFieldName(ref name, attrib, "Name");
                    GetFieldBoolean(ref isRequired, attrib, "IsRequired");
                    GetFieldBoolean(ref isPacked, attrib, "IsPacked");
                    GetDataFormat(ref dataFormat, attrib, "DataFormat");
                    done = fieldNumber > 0;
                }

                if (!done && partialMembers != null)
                {
                    foreach (ProtoPartialMemberAttribute ppma in partialMembers)
                    {
                        if (ppma.MemberName == member.Name)
                        {
                            GetFieldNumber(ref fieldNumber, ppma, "Tag");
                            GetFieldName(ref name, ppma, "Name");
                            GetFieldBoolean(ref isRequired, ppma, "IsRequired");
                            GetFieldBoolean(ref isPacked, ppma, "IsPacked");
                            GetDataFormat(ref dataFormat, ppma, "DataFormat");
                            if (done = fieldNumber > 0) break;                            
                        }
                    }
                }
            }
            if (!ignore && !done && HasFamily(family, AttributeFamily.DataContractSerialier))
            {
                attrib = GetAttribute(attribs, "System.Runtime.Serialization.DataMemberAttribute");
                GetFieldNumber(ref fieldNumber, attrib, "Order");
                GetFieldName(ref name, attrib, "Name");
                GetFieldBoolean(ref isRequired, attrib, "IsRequired");
                done = fieldNumber > 0;
            }
            if (!ignore && !done && HasFamily(family, AttributeFamily.XmlSerializer))
            {
                attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlElementAttribute");
                GetIgnore(ref ignore, attrib, attribs, "System.Xml.Serialization.XmlIgnoreAttribute");
                if (!ignore)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Order");
                    GetFieldName(ref name, attrib, "ElementName");
                }
                attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlArrayAttribute");
                GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.XmlIgnoreAttribute");
                if (!ignore)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Order");
                    GetFieldName(ref name, attrib, "ElementName");
                }
                done = fieldNumber > 0;
            }
            if (!ignore && (attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null)
            {
                defaultValue = GetMemberValue(attrib, "Value");
            }
            ValueMember vm = ((isEnum || fieldNumber > 0) && !ignore)
                ? new ValueMember(model, type, fieldNumber, member, effectiveType, itemType, defaultType, dataFormat, defaultValue)
                    : null;
            if (vm != null)
            {
                PropertyInfo prop = type.GetProperty(member.Name + "Specified", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                    null, typeof(bool), Helpers.EmptyTypes, null);
                if (prop != null)
                {
                    vm.SetSpecified(prop.GetGetMethod(true), prop.GetSetMethod(true));
                }
                else
                {
                    MethodInfo method = type.GetMethod("ShouldSerialize" + member.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                        null, Helpers.EmptyTypes, null);
                    if (method != null && method.ReturnType == typeof(bool))
                    {
                        vm.SetSpecified(method, null);
                    }
                }
                if(!Helpers.IsNullOrEmpty(name)) vm.SetName(name);
                vm.IsPacked = isPacked;
                vm.IsRequired = isRequired;
            }
            return vm;
        }
Example #38
0
        /// <summary>
        /// Fully compiles the current model into a static-compiled serialization dll
        /// (the serialization dll still requires protobuf-net for support services).
        /// </summary>
        /// <remarks>A full compilation is restricted to accessing public types / members</remarks>
        /// <returns>An instance of the newly created compiled type-model</returns>
        public TypeModel Compile(CompilerOptions options)
        {
            if (options == null) throw new ArgumentNullException("options");
            string typeName = options.TypeName;
            string path = options.OutputPath;
            BuildAllSerializers();
            Freeze();
            bool save = !Helpers.IsNullOrEmpty(path);
            if (Helpers.IsNullOrEmpty(typeName))
            {
                if (save) throw new ArgumentNullException("typeName");
                typeName = Guid.NewGuid().ToString();
            }


            string assemblyName, moduleName;
            if(path == null)
            {
                assemblyName = typeName;
                moduleName = assemblyName + ".dll";
            }
            else
            {
                assemblyName = new System.IO.FileInfo(System.IO.Path.GetFileNameWithoutExtension(path)).Name;
                moduleName = assemblyName + System.IO.Path.GetExtension(path);
            }

#if FEAT_IKVM
            IKVM.Reflection.AssemblyName an = new IKVM.Reflection.AssemblyName();
            an.Name = assemblyName;
            AssemblyBuilder asm = universe.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save);
            if(!Helpers.IsNullOrEmpty(options.ImageRuntimeVersion) && options.MetaDataVersion != 0)
            {
                asm.__SetImageRuntimeVersion(options.ImageRuntimeVersion, options.MetaDataVersion);
            }
            ModuleBuilder module = asm.DefineDynamicModule(moduleName, path);
#else
            AssemblyName an = new AssemblyName();
            an.Name = assemblyName;
            AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(an,
                (save ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run)
                );
            ModuleBuilder module = save ? asm.DefineDynamicModule(moduleName, path)
                                        : asm.DefineDynamicModule(moduleName);
#endif

            if (!Helpers.IsNullOrEmpty(options.TargetFrameworkName))
            {
                // get [TargetFramework] from mscorlib/equivalent and burn into the new assembly
                Type versionAttribType = null;
                try
                { // this is best-endeavours only
                    versionAttribType = GetType("System.Runtime.Versioning.TargetFrameworkAttribute", MapType(typeof(string)).Assembly);
                }
                catch { /* don't stress */ }
                if (versionAttribType != null)
                {
                    PropertyInfo[] props;
                    object[] propValues;
                    if (Helpers.IsNullOrEmpty(options.TargetFrameworkDisplayName))
                    {
                        props = new PropertyInfo[0];
                        propValues = new object[0];
                    }
                    else
                    {
                        props = new PropertyInfo[1] { versionAttribType.GetProperty("FrameworkDisplayName") };
                        propValues = new object[1] { options.TargetFrameworkDisplayName };
                    }
                    CustomAttributeBuilder builder = new CustomAttributeBuilder(
                        versionAttribType.GetConstructor(new Type[] { MapType(typeof(string)) }),
                        new object[] { options.TargetFrameworkName },
                        props,
                        propValues);
                    asm.SetCustomAttribute(builder);
                }
            }

            // copy assembly:InternalsVisibleTo
            Type internalsVisibleToAttribType = null;
#if !FX11
            try
            {
                internalsVisibleToAttribType = MapType(typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute));
            }
            catch { /* best endeavors only */ }
#endif   
            if (internalsVisibleToAttribType != null)
            {
                BasicList internalAssemblies = new BasicList(), consideredAssemblies = new BasicList();
                foreach (MetaType metaType in types)
                {
                    Assembly assembly = metaType.Type.Assembly;
                    if (consideredAssemblies.IndexOfReference(assembly) >= 0) continue;
                    consideredAssemblies.Add(assembly);

                    AttributeMap[] assemblyAttribsMap = AttributeMap.Create(this, assembly);
                    for (int i = 0; i < assemblyAttribsMap.Length; i++)
                    {
                        
                        if (assemblyAttribsMap[i].AttributeType != internalsVisibleToAttribType) continue;

                        object privelegedAssemblyObj;
                        assemblyAttribsMap[i].TryGet("AssemblyName", out privelegedAssemblyObj);
                        string privelegedAssemblyName = privelegedAssemblyObj as string;
                        if (privelegedAssemblyName == assemblyName || Helpers.IsNullOrEmpty(privelegedAssemblyName)) continue; // ignore

                        if (internalAssemblies.IndexOf(new StringFinder(privelegedAssemblyName)) >= 0) continue; // seen it before
                        internalAssemblies.Add(privelegedAssemblyName);


                        CustomAttributeBuilder builder = new CustomAttributeBuilder(
                            internalsVisibleToAttribType.GetConstructor(new Type[] { MapType(typeof(string)) }),
                            new object[] { privelegedAssemblyName });
                        asm.SetCustomAttribute(builder);
                    }
                }
            }
            Type baseType = MapType(typeof(TypeModel));
            TypeAttributes typeAttributes = (baseType.Attributes & ~TypeAttributes.Abstract) | TypeAttributes.Sealed;
            if(options.Accessibility == Accessibility.Internal)
            {
                typeAttributes &= ~TypeAttributes.Public;
            }
            
            TypeBuilder type = module.DefineType(typeName, typeAttributes, baseType);
            Compiler.CompilerContext ctx;
            
            int index = 0;
            bool hasInheritance = false;
            SerializerPair[] methodPairs = new SerializerPair[types.Count];
            foreach (MetaType metaType in types)
            {
                MethodBuilder writeMethod = type.DefineMethod("Write"
#if DEBUG
 + metaType.Type.Name
#endif
                    ,
                    MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard,
                    MapType(typeof(void)), new Type[] { metaType.Type, MapType(typeof(ProtoWriter)) });

                MethodBuilder readMethod = type.DefineMethod("Read"
#if DEBUG
 + metaType.Type.Name
#endif              
                    ,
                    MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard,
                    metaType.Type, new Type[] { metaType.Type, MapType(typeof(ProtoReader)) });

                SerializerPair pair = new SerializerPair(
                    GetKey(metaType.Type, true, false), GetKey(metaType.Type, true, true), metaType,
                    writeMethod, readMethod, writeMethod.GetILGenerator(), readMethod.GetILGenerator());
                methodPairs[index++] = pair;
                if (pair.MetaKey != pair.BaseKey) hasInheritance = true;
            }
            if (hasInheritance)
            {
                Array.Sort(methodPairs);
            }

            Compiler.CompilerContext.ILVersion ilVersion = Compiler.CompilerContext.ILVersion.Net2;
            if (options.MetaDataVersion == 0x10000)
            {
                ilVersion = Compiler.CompilerContext.ILVersion.Net1; // old-school!
            }
            for(index = 0; index < methodPairs.Length ; index++)
            {
                SerializerPair pair = methodPairs[index];
                ctx = new Compiler.CompilerContext(pair.SerializeBody, true, true, methodPairs, this, ilVersion, assemblyName);
                ctx.CheckAccessibility(pair.Deserialize.ReturnType);
                pair.Type.Serializer.EmitWrite(ctx, Compiler.Local.InputValue);
                ctx.Return();

                ctx = new Compiler.CompilerContext(pair.DeserializeBody, true, false, methodPairs, this, ilVersion, assemblyName);
                pair.Type.Serializer.EmitRead(ctx, Compiler.Local.InputValue);
                if (!pair.Type.Serializer.ReturnsValue)
                {
                    ctx.LoadValue(Compiler.Local.InputValue);
                }
                ctx.Return();
            }

            ILGenerator il = Override(type, "GetKeyImpl");
            int knownTypesCategory;
            FieldBuilder knownTypes;
            Type knownTypesLookupType;
            const int KnownTypes_Array = 1, KnownTypes_Dictionary = 2, KnownTypes_Hashtable = 3, KnownTypes_ArrayCutoff = 20;

            if (types.Count <= KnownTypes_ArrayCutoff)
            {
                knownTypesCategory = KnownTypes_Array;
                knownTypesLookupType = MapType(typeof(System.Type[]), true);
            }
            else
            {
#if NO_GENERICS
                knownTypesLookupType = null;
#else
                knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary<System.Type, int>), false);
#endif
                if (knownTypesLookupType == null)
                {
                    knownTypesLookupType = MapType(typeof(Hashtable), true);
                    knownTypesCategory = KnownTypes_Hashtable;
                }
                else
                {
                    knownTypesCategory = KnownTypes_Dictionary; 
                }
            }
            knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static);
            
            switch(knownTypesCategory)
            {
                case KnownTypes_Array:
                    {
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        // note that Array.IndexOf is not supported under CF
                        il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod(
                            "IndexOf", new Type[] { MapType(typeof(object)) }), null);
                        if (hasInheritance)
                        {
                            il.DeclareLocal(MapType(typeof(int))); // loc-0
                            il.Emit(OpCodes.Dup);
                            il.Emit(OpCodes.Stloc_0);

                            BasicList getKeyLabels = new BasicList();
                            int lastKey = -1;
                            for (int i = 0; i < methodPairs.Length; i++)
                            {
                                if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) break;
                                if (lastKey == methodPairs[i].BaseKey)
                                {   // add the last label again
                                    getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]);
                                }
                                else
                                {   // add a new unique label
                                    getKeyLabels.Add(il.DefineLabel());
                                    lastKey = methodPairs[i].BaseKey;
                                }
                            }
                            Label[] subtypeLabels = new Label[getKeyLabels.Count];
                            getKeyLabels.CopyTo(subtypeLabels, 0);

                            il.Emit(OpCodes.Switch, subtypeLabels);
                            il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value
                            il.Emit(OpCodes.Ret);

                            lastKey = -1;
                            // now output the different branches per sub-type (not derived type)
                            for (int i = subtypeLabels.Length - 1; i >= 0; i--)
                            {
                                if (lastKey != methodPairs[i].BaseKey)
                                {
                                    lastKey = methodPairs[i].BaseKey;
                                    // find the actual base-index for this base-key (i.e. the index of
                                    // the base-type)
                                    int keyIndex = -1;
                                    for (int j = subtypeLabels.Length; j < methodPairs.Length; j++)
                                    {
                                        if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                                        {
                                            keyIndex = j;
                                            break;
                                        }
                                    }
                                    il.MarkLabel(subtypeLabels[i]);
                                    Compiler.CompilerContext.LoadValue(il, keyIndex);
                                    il.Emit(OpCodes.Ret);
                                }
                            }
                        }
                        else
                        {
                            il.Emit(OpCodes.Ret);
                        }
                    }
                    break;
                case KnownTypes_Dictionary:
                    {
                        LocalBuilder result = il.DeclareLocal(MapType(typeof(int)));
                        Label otherwise = il.DefineLabel();
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Ldloca_S, result);
                        il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null);
                        il.Emit(OpCodes.Brfalse_S, otherwise);
                        il.Emit(OpCodes.Ldloc_S, result);
                        il.Emit(OpCodes.Ret);
                        il.MarkLabel(otherwise);
                        il.Emit(OpCodes.Ldc_I4_M1);
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                case KnownTypes_Hashtable:
                    {
                        Label otherwise = il.DefineLabel();
                        il.Emit(OpCodes.Ldsfld, knownTypes);
                        il.Emit(OpCodes.Ldarg_1);
                        il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null);
                        il.Emit(OpCodes.Dup);
                        il.Emit(OpCodes.Brfalse_S, otherwise);
#if FX11
                        il.Emit(OpCodes.Unbox, MapType(typeof(int)));
                        il.Emit(OpCodes.Ldobj, MapType(typeof(int)));
#else
                        if (ilVersion == Compiler.CompilerContext.ILVersion.Net1)
                        {
                            il.Emit(OpCodes.Unbox, MapType(typeof(int)));
                            il.Emit(OpCodes.Ldobj, MapType(typeof(int)));
                        }
                        else
                        {
                            il.Emit(OpCodes.Unbox_Any, MapType(typeof(int)));
                        }
#endif
                        il.Emit(OpCodes.Ret);
                        il.MarkLabel(otherwise);
                        il.Emit(OpCodes.Pop);
                        il.Emit(OpCodes.Ldc_I4_M1);
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                default:
                    throw new InvalidOperationException();
            }
            
            il = Override(type, "Serialize");
            ctx = new Compiler.CompilerContext(il, false, true, methodPairs, this, ilVersion, assemblyName);
            // arg0 = this, arg1 = key, arg2=obj, arg3=dest
            Label[] jumpTable = new Label[types.Count];
            for (int i = 0; i < jumpTable.Length; i++) {
                jumpTable[i] = il.DefineLabel();
            }
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Switch, jumpTable);
            ctx.Return();
            for (int i = 0; i < jumpTable.Length; i++)
            {
                SerializerPair pair = methodPairs[i];
                il.MarkLabel(jumpTable[i]);
                il.Emit(OpCodes.Ldarg_2);
                ctx.CastFromObject(pair.Type.Type);
                il.Emit(OpCodes.Ldarg_3);
                il.EmitCall(OpCodes.Call, pair.Serialize, null);
                ctx.Return();
            }

            il = Override(type, "Deserialize");
            ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName);
            // arg0 = this, arg1 = key, arg2=obj, arg3=source
            for (int i = 0; i < jumpTable.Length; i++)
            {
                jumpTable[i] = il.DefineLabel();
            }
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Switch, jumpTable);
            ctx.LoadNullRef();
            ctx.Return();
            for (int i = 0; i < jumpTable.Length; i++)
            {
                SerializerPair pair = methodPairs[i];
                il.MarkLabel(jumpTable[i]);
                Type keyType = pair.Type.Type;
                if (keyType.IsValueType)
                {
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Ldarg_3);
                    il.EmitCall(OpCodes.Call, EmitBoxedSerializer(type, i, keyType, methodPairs, this, ilVersion, assemblyName), null);
                    ctx.Return();
                }
                else
                {
                    il.Emit(OpCodes.Ldarg_2);
                    ctx.CastFromObject(keyType);
                    il.Emit(OpCodes.Ldarg_3);
                    il.EmitCall(OpCodes.Call, pair.Deserialize, null);
                    ctx.Return();
                }
            }
            type.DefineDefaultConstructor(MethodAttributes.Public);
            il = type.DefineTypeInitializer().GetILGenerator();
            switch (knownTypesCategory)
            {
                case KnownTypes_Array:
                    {
                        Compiler.CompilerContext.LoadValue(il, types.Count);
                        il.Emit(OpCodes.Newarr, ctx.MapType(typeof(System.Type)));
                        index = 0;
                        foreach (SerializerPair pair in methodPairs)
                        {
                            il.Emit(OpCodes.Dup);
                            Compiler.CompilerContext.LoadValue(il, index);
                            il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                            il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                            il.Emit(OpCodes.Stelem_Ref);
                            index++;
                        }
                        il.Emit(OpCodes.Stsfld, knownTypes);
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                case KnownTypes_Dictionary:
                    {
                        Compiler.CompilerContext.LoadValue(il, types.Count);
                        LocalBuilder loc = il.DeclareLocal(knownTypesLookupType);
                        il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) }));
                        il.Emit(OpCodes.Stsfld, knownTypes);
                        int typeIndex = 0;
                        foreach (SerializerPair pair in methodPairs)
                        {
                            il.Emit(OpCodes.Ldsfld, knownTypes);
                            il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                            il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                            int keyIndex = typeIndex++, lastKey = pair.BaseKey;
                            if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type
                            {
                                keyIndex = -1; // assume epic fail
                                for (int j = 0; j < methodPairs.Length; j++)
                                {
                                    if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                                    {
                                        keyIndex = j;
                                        break;
                                    }
                                }
                            }
                            Compiler.CompilerContext.LoadValue(il, keyIndex);
                            il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(System.Type)), MapType(typeof(int)) }), null);
                        }
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                case KnownTypes_Hashtable:
                    {
                        Compiler.CompilerContext.LoadValue(il, types.Count);
                        il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) }));
                        il.Emit(OpCodes.Stsfld, knownTypes);
                        int typeIndex = 0;
                        foreach (SerializerPair pair in methodPairs)
                        {
                            il.Emit(OpCodes.Ldsfld, knownTypes);
                            il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                            il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null);
                            int keyIndex = typeIndex++, lastKey = pair.BaseKey;
                            if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type
                            {
                                keyIndex = -1; // assume epic fail
                                for (int j = 0; j < methodPairs.Length; j++)
                                {
                                    if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                                    {
                                        keyIndex = j;
                                        break;
                                    }
                                }
                            }
                            Compiler.CompilerContext.LoadValue(il, keyIndex);
                            il.Emit(OpCodes.Box, MapType(typeof(int)));
                            il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(object)), MapType(typeof(object)) }), null);
                        }
                        il.Emit(OpCodes.Ret);
                    }
                    break;
                default:
                    throw new InvalidOperationException();
            }
            


            Type finalType = type.CreateType();
            if(!Helpers.IsNullOrEmpty(path))
            {
                asm.Save(path);
                Helpers.DebugWriteLine("Wrote dll:" + path);
            }
#if FEAT_IKVM
            return null;
#else
            return (TypeModel)Activator.CreateInstance(finalType);
#endif
        }
Example #39
0
        private IProtoTypeSerializer BuildSerializer()
        {
            if (surrogate != null)
            {
                MetaType mt = model[surrogate], mtBase;
                while ((mtBase = mt.baseType) != null)
                {
                    mt = mtBase;
                }
                return(new SurrogateSerializer(type, surrogate, mt.Serializer));
            }

            Type itemType = TypeModel.GetListItemType(type);

            if (itemType != null)
            {
                ValueMember fakeMember = new ValueMember(model, 1, type, itemType, type, DataFormat.Default);
                return(new TypeSerializer(type, new int[] { 1 }, new IProtoSerializer[] { fakeMember.Serializer }, null, true, true, null, constructType));
            }

            fields.Trim();
            int fieldCount   = fields.Count;
            int subTypeCount = subTypes == null ? 0 : subTypes.Count;

            int[] fieldNumbers             = new int[fieldCount + subTypeCount];
            IProtoSerializer[] serializers = new IProtoSerializer[fieldCount + subTypeCount];
            int i = 0;

            if (subTypeCount != 0)
            {
                foreach (SubType subType in subTypes)
                {
                    fieldNumbers[i]  = subType.FieldNumber;
                    serializers[i++] = subType.Serializer;
                }
            }
            if (fieldCount != 0)
            {
                foreach (ValueMember member in fields)
                {
                    fieldNumbers[i]  = member.FieldNumber;
                    serializers[i++] = member.Serializer;
                }
            }

            BasicList baseCtorCallbacks = null;
            MetaType  tmp = BaseType;

            while (tmp != null)
            {
                MethodInfo method = tmp.HasCallbacks ? tmp.Callbacks.BeforeDeserialize : null;
                if (method != null)
                {
                    if (baseCtorCallbacks == null)
                    {
                        baseCtorCallbacks = new BasicList();
                    }
                    baseCtorCallbacks.Add(method);
                }
                tmp = tmp.BaseType;
            }
            MethodInfo[] arr = null;
            if (baseCtorCallbacks != null)
            {
                arr = new MethodInfo[baseCtorCallbacks.Count];
                baseCtorCallbacks.CopyTo(arr, 0);
                Array.Reverse(arr);
            }
            return(new TypeSerializer(type, fieldNumbers, serializers, arr, baseType == null, UseConstructor, callbacks, constructType));
        }
        // Token: 0x06000369 RID: 873 RVA: 0x00012780 File Offset: 0x00010980
        public override string GetSchema(Type type)
        {
            BasicList basicList = new BasicList();
            MetaType  metaType  = null;
            bool      flag      = false;

            if (type == null)
            {
                foreach (object obj in this.types)
                {
                    MetaType surrogateOrBaseOrSelf = ((MetaType)obj).GetSurrogateOrBaseOrSelf(false);
                    if (!basicList.Contains(surrogateOrBaseOrSelf))
                    {
                        basicList.Add(surrogateOrBaseOrSelf);
                        this.CascadeDependents(basicList, surrogateOrBaseOrSelf);
                    }
                }
            }
            else
            {
                Type underlyingType = Helpers.GetUnderlyingType(type);
                if (underlyingType != null)
                {
                    type = underlyingType;
                }
                WireType wireType;
                flag = (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out wireType, false, false, false, false) != null);
                if (!flag)
                {
                    int num = this.FindOrAddAuto(type, false, false, false);
                    if (num < 0)
                    {
                        throw new ArgumentException("The type specified is not a contract-type", "type");
                    }
                    metaType = ((MetaType)this.types[num]).GetSurrogateOrBaseOrSelf(false);
                    basicList.Add(metaType);
                    this.CascadeDependents(basicList, metaType);
                }
            }
            StringBuilder stringBuilder = new StringBuilder();
            string        text          = null;

            if (!flag)
            {
                foreach (object obj2 in ((IEnumerable)((metaType == null) ? this.types : basicList)))
                {
                    MetaType metaType2 = (MetaType)obj2;
                    if (!metaType2.IsList)
                    {
                        string @namespace = metaType2.Type.Namespace;
                        if (!Helpers.IsNullOrEmpty(@namespace) && [email protected]("System."))
                        {
                            if (text == null)
                            {
                                text = @namespace;
                            }
                            else if (!(text == @namespace))
                            {
                                text = null;
                                break;
                            }
                        }
                    }
                }
            }
            if (!Helpers.IsNullOrEmpty(text))
            {
                stringBuilder.Append("package ").Append(text).Append(';');
                Helpers.AppendLine(stringBuilder);
            }
            bool          flag2          = false;
            StringBuilder stringBuilder2 = new StringBuilder();

            MetaType[] array = new MetaType[basicList.Count];
            basicList.CopyTo(array, 0);
            Array.Sort <MetaType>(array, MetaType.Comparer.Default);
            if (flag)
            {
                Helpers.AppendLine(stringBuilder2).Append("message ").Append(type.Name).Append(" {");
                MetaType.NewLine(stringBuilder2, 1).Append("optional ").Append(this.GetSchemaTypeName(type, DataFormat.Default, false, false, ref flag2)).Append(" value = 1;");
                Helpers.AppendLine(stringBuilder2).Append('}');
            }
            else
            {
                foreach (MetaType metaType3 in array)
                {
                    if (!metaType3.IsList || metaType3 == metaType)
                    {
                        metaType3.WriteSchema(stringBuilder2, 0, ref flag2);
                    }
                }
            }
            if (flag2)
            {
                stringBuilder.Append("import \"bcl.proto\"; // schema for protobuf-net's handling of core .NET types");
                Helpers.AppendLine(stringBuilder);
            }
            return(Helpers.AppendLine(stringBuilder.Append(stringBuilder2)).ToString());
        }
Example #41
0
 private void CascadeDependents(BasicList list, MetaType metaType)
 {
     if (metaType.IsList)
     {
         Type     listItemType = TypeModel.GetListItemType(this, metaType.Type);
         WireType wireType;
         if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, listItemType, out wireType, false, false, false, false) == null)
         {
             int num = this.FindOrAddAuto(listItemType, false, false, false);
             if (num >= 0)
             {
                 MetaType metaType2 = ((MetaType)this.types[num]).GetSurrogateOrBaseOrSelf(false);
                 if (!list.Contains(metaType2))
                 {
                     list.Add(metaType2);
                     this.CascadeDependents(list, metaType2);
                 }
             }
         }
     }
     else
     {
         MetaType metaType2;
         if (metaType.IsAutoTuple)
         {
             MemberInfo[] array;
             if (MetaType.ResolveTupleConstructor(metaType.Type, out array) != null)
             {
                 for (int i = 0; i < array.Length; i++)
                 {
                     Type type = null;
                     if (array[i] is PropertyInfo)
                     {
                         type = ((PropertyInfo)array[i]).get_PropertyType();
                     }
                     else if (array[i] is FieldInfo)
                     {
                         type = ((FieldInfo)array[i]).get_FieldType();
                     }
                     WireType wireType2;
                     if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out wireType2, false, false, false, false) == null)
                     {
                         int num2 = this.FindOrAddAuto(type, false, false, false);
                         if (num2 >= 0)
                         {
                             metaType2 = ((MetaType)this.types[num2]).GetSurrogateOrBaseOrSelf(false);
                             if (!list.Contains(metaType2))
                             {
                                 list.Add(metaType2);
                                 this.CascadeDependents(list, metaType2);
                             }
                         }
                     }
                 }
             }
         }
         else
         {
             IEnumerator enumerator = metaType.Fields.GetEnumerator();
             try
             {
                 while (enumerator.MoveNext())
                 {
                     ValueMember valueMember = (ValueMember)enumerator.get_Current();
                     Type        type2       = valueMember.ItemType;
                     if (type2 == null)
                     {
                         type2 = valueMember.MemberType;
                     }
                     WireType wireType3;
                     if (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type2, out wireType3, false, false, false, false) == null)
                     {
                         int num3 = this.FindOrAddAuto(type2, false, false, false);
                         if (num3 >= 0)
                         {
                             metaType2 = ((MetaType)this.types[num3]).GetSurrogateOrBaseOrSelf(false);
                             if (!list.Contains(metaType2))
                             {
                                 list.Add(metaType2);
                                 this.CascadeDependents(list, metaType2);
                             }
                         }
                     }
                 }
             }
             finally
             {
                 IDisposable disposable = enumerator as IDisposable;
                 if (disposable != null)
                 {
                     disposable.Dispose();
                 }
             }
         }
         if (metaType.HasSubtypes)
         {
             SubType[] subtypes = metaType.GetSubtypes();
             for (int j = 0; j < subtypes.Length; j++)
             {
                 SubType subType = subtypes[j];
                 metaType2 = subType.DerivedType.GetSurrogateOrSelf();
                 if (!list.Contains(metaType2))
                 {
                     list.Add(metaType2);
                     this.CascadeDependents(list, metaType2);
                 }
             }
         }
         metaType2 = metaType.BaseType;
         if (metaType2 != null)
         {
             metaType2 = metaType2.GetSurrogateOrSelf();
         }
         if (metaType2 != null && !list.Contains(metaType2))
         {
             list.Add(metaType2);
             this.CascadeDependents(list, metaType2);
         }
     }
 }
Example #42
0
        public override string GetSchema(Type type)
        {
            BasicList basicList = new BasicList();
            MetaType  metaType  = null;
            bool      flag      = false;

            if (type == null)
            {
                BasicList.NodeEnumerator enumerator = this.types.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    MetaType metaType2             = (MetaType)enumerator.Current;
                    MetaType surrogateOrBaseOrSelf = metaType2.GetSurrogateOrBaseOrSelf(false);
                    if (!basicList.Contains(surrogateOrBaseOrSelf))
                    {
                        basicList.Add(surrogateOrBaseOrSelf);
                        this.CascadeDependents(basicList, surrogateOrBaseOrSelf);
                    }
                }
            }
            else
            {
                Type underlyingType = Helpers.GetUnderlyingType(type);
                if (underlyingType != null)
                {
                    type = underlyingType;
                }
                WireType wireType;
                flag = (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out wireType, false, false, false, false) != null);
                if (!flag)
                {
                    int num = this.FindOrAddAuto(type, false, false, false);
                    if (num < 0)
                    {
                        throw new ArgumentException("The type specified is not a contract-type", "type");
                    }
                    metaType = ((MetaType)this.types[num]).GetSurrogateOrBaseOrSelf(false);
                    basicList.Add(metaType);
                    this.CascadeDependents(basicList, metaType);
                }
            }
            StringBuilder stringBuilder = new StringBuilder();
            string        text          = null;

            if (!flag)
            {
                IEnumerable enumerable  = (metaType != null) ? basicList : this.types;
                IEnumerator enumerator2 = enumerable.GetEnumerator();
                try
                {
                    while (enumerator2.MoveNext())
                    {
                        MetaType metaType3 = (MetaType)enumerator2.get_Current();
                        if (!metaType3.IsList)
                        {
                            string @namespace = metaType3.Type.get_Namespace();
                            if (!Helpers.IsNullOrEmpty(@namespace))
                            {
                                if ([email protected]("System."))
                                {
                                    if (text == null)
                                    {
                                        text = @namespace;
                                    }
                                    else if (!(text == @namespace))
                                    {
                                        text = null;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    IDisposable disposable = enumerator2 as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }
                }
            }
            if (!Helpers.IsNullOrEmpty(text))
            {
                stringBuilder.Append("package ").Append(text).Append(';');
                Helpers.AppendLine(stringBuilder);
            }
            bool          flag2          = false;
            StringBuilder stringBuilder2 = new StringBuilder();

            MetaType[] array = new MetaType[basicList.Count];
            basicList.CopyTo(array, 0);
            Array.Sort <MetaType>(array, MetaType.Comparer.Default);
            if (flag)
            {
                Helpers.AppendLine(stringBuilder2).Append("message ").Append(type.get_Name()).Append(" {");
                MetaType.NewLine(stringBuilder2, 1).Append("optional ").Append(this.GetSchemaTypeName(type, DataFormat.Default, false, false, ref flag2)).Append(" value = 1;");
                Helpers.AppendLine(stringBuilder2).Append('}');
            }
            else
            {
                for (int i = 0; i < array.Length; i++)
                {
                    MetaType metaType4 = array[i];
                    if (!metaType4.IsList || metaType4 == metaType)
                    {
                        metaType4.WriteSchema(stringBuilder2, 0, ref flag2);
                    }
                }
            }
            if (flag2)
            {
                stringBuilder.Append("import \"bcl.proto\"; // schema for protobuf-net's handling of core .NET types");
                Helpers.AppendLine(stringBuilder);
            }
            return(Helpers.AppendLine(stringBuilder.Append(stringBuilder2)).ToString());
        }
        internal static Type GetListItemType(Type listType)
        {
            Helpers.DebugAssert(listType != null);
            if (listType == typeof(string) || listType.IsArray
                || !typeof(IEnumerable).IsAssignableFrom(listType)) return null;

            BasicList candidates = new BasicList();
            candidates.Add(typeof(object));
            foreach (MethodInfo method in listType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
            {
                if (method.Name != "Add") continue;
                ParameterInfo[] parameters = method.GetParameters();
                if (parameters.Length == 1 && !candidates.Contains(parameters[0].ParameterType))
                {
                    candidates.Add(parameters[0].ParameterType);
                }
            }
            foreach (Type iType in listType.GetInterfaces())
            {
                if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(System.Collections.Generic.ICollection<>))
                {
                    Type[] iTypeArgs = iType.GetGenericArguments();
                    if (!candidates.Contains(iTypeArgs[0]))
                    {
                        candidates.Add(iTypeArgs[0]);
                    }
                }
            }
            // more convenient GetProperty overload not supported on all platforms
            foreach (PropertyInfo indexer in listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) continue;
                ParameterInfo[] args = indexer.GetIndexParameters();
                if (args.Length != 1 || args[0].ParameterType != typeof(int)) continue;
                candidates.Add(indexer.PropertyType);
            }

            switch (candidates.Count)
            {
                case 1:
                    return null;
                case 2:
                    return (Type)candidates[1];
                case 3:
                    if (CheckDictionaryAccessors((Type)candidates[1], (Type)candidates[2])) return (Type)candidates[1];
                    if (CheckDictionaryAccessors((Type)candidates[2], (Type)candidates[1])) return (Type)candidates[2];
                    break;
            }

            return null;
        }
Example #44
0
 internal int IndexOf(BasicList.MatchPredicate predicate, object ctx)
 {
     return this.head.IndexOf(predicate, ctx);
 }
		private BasicList GetNestedListHierarchy(Type type)
		{
			BasicList list = new BasicList();
			
			Type itemT;
			Type defaultT;

			do
			{
				itemT = null;
				defaultT = null;

				MetaType.ResolveListTypes(type, ref itemT, ref defaultT);
				list.Add(new NestedItem(type, itemT, defaultT));

				type = itemT;
			} while (itemT != null);

			return list;
		}
Example #46
0
 internal int IndexOf(BasicList.MatchPredicate predicate, object ctx)
 {
     for (int i = 0; i < this.length; i++)
     {
         if (predicate(this.data[i], ctx))
         {
             return i;
         }
     }
     return -1;
 }
		private bool HasAutoDynamicHandling(BasicList nestedHierarchy)
		{
			int hierarchyCount = nestedHierarchy.Count;
			
			for (int i = 0; i < hierarchyCount - 1; i++)
			{
				NestedItem item = (NestedItem) nestedHierarchy[i];
				MetaType metaType = model.FindWithoutAdd(item.Type);

				if (metaType != null && metaType.AutoDynamicHandling)
				{
					return true;
				}
			}

			return false;
		}
        /// <summary>
        /// Suggest a .proto definition for the given type
        /// </summary>
        /// <param name="type">The type to generate a .proto definition for, or <c>null</c> to generate a .proto that represents the entire model</param>
        /// <returns>The .proto definition as a string</returns>
        public override string GetSchema(Type type)
        {
            BasicList requiredTypes = new BasicList();
            MetaType primaryType = null;
            bool isInbuiltType = false;
            if (type == null)
            { // generate for the entire model
                foreach(MetaType meta in types)
                {
                    MetaType tmp = meta.GetSurrogateOrBaseOrSelf(false);
                    if (!requiredTypes.Contains(tmp))
                    { // ^^^ note that the type might have been added as a descendent
                        requiredTypes.Add(tmp);
                        CascadeDependents(requiredTypes, tmp);
                    }
                }
            }
            else
            {
                Type tmp = Helpers.GetUnderlyingType(type);
                if (tmp != null) type = tmp;

                WireType defaultWireType;
                isInbuiltType = (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false) != null);
                if (!isInbuiltType)
                {
                    //Agenerate just relative to the supplied type
                    int index = FindOrAddAuto(type, false, false, false);
                    if (index < 0) throw new ArgumentException("The type specified is not a contract-type", "type");

                    // get the required types
                    primaryType = ((MetaType)types[index]).GetSurrogateOrBaseOrSelf(false);
                    requiredTypes.Add(primaryType);
                    CascadeDependents(requiredTypes, primaryType);
                }
            }

            // use the provided type's namespace for the "package"
            StringBuilder headerBuilder = new StringBuilder();
            string package = null;

            if (!isInbuiltType)
            {
                IEnumerable typesForNamespace = primaryType == null ? types : requiredTypes;
                foreach (MetaType meta in typesForNamespace)
                {
                    if (meta.IsList) continue;
                    string tmp = meta.Type.Namespace;
                    if (!Helpers.IsNullOrEmpty(tmp))
                    {
                        if (tmp.StartsWith("System.")) continue;
                        if (package == null)
                        { // haven't seen any suggestions yet
                            package = tmp;
                        }
                        else if (package == tmp)
                        { // that's fine; a repeat of the one we already saw
                        }
                        else
                        { // something else; have confliucting suggestions; abort
                            package = null;
                            break;
                        }
                    }
                }
            }

            if (!Helpers.IsNullOrEmpty(package))
            {
                headerBuilder.Append("package ").Append(package).Append(';');
                Helpers.AppendLine(headerBuilder);
            }

            bool requiresBclImport = false;
            StringBuilder bodyBuilder = new StringBuilder();
            // sort them by schema-name
            MetaType[] metaTypesArr = new MetaType[requiredTypes.Count];
            requiredTypes.CopyTo(metaTypesArr, 0);
            Array.Sort(metaTypesArr, MetaType.Comparer.Default);

            // write the messages
            if (isInbuiltType)
            {
                Helpers.AppendLine(bodyBuilder).Append("message ").Append(type.Name).Append(" {");
                MetaType.NewLine(bodyBuilder, 1).Append("optional ").Append(GetSchemaTypeName(type, DataFormat.Default, false, false, ref requiresBclImport))
                    .Append(" value = 1;");
                Helpers.AppendLine(bodyBuilder).Append('}');
            }
            else
            {
                for (int i = 0; i < metaTypesArr.Length; i++)
                {
                    MetaType tmp = metaTypesArr[i];
                    if (tmp.IsList && tmp != primaryType) continue;
                    tmp.WriteSchema(bodyBuilder, 0, ref requiresBclImport);
                }
            }
            if (requiresBclImport)
            {
                headerBuilder.Append("import \"bcl.proto\"; // schema for protobuf-net's handling of core .NET types");
                Helpers.AppendLine(headerBuilder);
            }
            return Helpers.AppendLine(headerBuilder.Append(bodyBuilder)).ToString();
        }
		private IProtoSerializer GetNestedSerializer(Type type, out WireType wireType)
		{
			MetaType metaType = model.FindWithoutAdd(type);

			BasicList hierarchy = GetNestedListHierarchy(type);

			if (hierarchy.Count > 1 && metaType != null && metaType.IgnoreListHandling)
			{
				hierarchy = new BasicList();
				hierarchy.Add(new NestedItem(type, null, null));
			}

			return GetNestedSerializer(hierarchy, out wireType);
		}
        private void CascadeDependents(BasicList list, MetaType metaType)
        {
            MetaType tmp;
            if (metaType.IsList)
            {
                Type itemType = TypeModel.GetListItemType(this, metaType.Type);
                WireType defaultWireType;
                IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, itemType, out defaultWireType, false, false, false, false);
                if (coreSerializer == null)
                {
                    int index = FindOrAddAuto(itemType, false, false, false);
                    if (index >= 0)
                    {
                        tmp = ((MetaType)types[index]).GetSurrogateOrBaseOrSelf(false);
                        if (!list.Contains(tmp))
                        { // could perhaps also implement as a queue, but this should work OK for sane models
                            list.Add(tmp);
                            CascadeDependents(list, tmp);
                        }
                    }
                }
            }
            else
            {
                if (metaType.IsAutoTuple)
                {
                    MemberInfo[] mapping;
                    if(MetaType.ResolveTupleConstructor(metaType.Type, out mapping) != null)
                    {
                        for (int i = 0; i < mapping.Length; i++)
                        {
                            Type type = null;
                            if (mapping[i] is PropertyInfo) type = ((PropertyInfo)mapping[i]).PropertyType;
                            else if (mapping[i] is FieldInfo) type = ((FieldInfo)mapping[i]).FieldType;

                            WireType defaultWireType;
                            IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false);
                            if (coreSerializer == null)
                            {
                                int index = FindOrAddAuto(type, false, false, false);
                                if (index >= 0)
                                {
                                    tmp = ((MetaType)types[index]).GetSurrogateOrBaseOrSelf(false);
                                    if (!list.Contains(tmp))
                                    { // could perhaps also implement as a queue, but this should work OK for sane models
                                        list.Add(tmp);
                                        CascadeDependents(list, tmp);
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    foreach (ValueMember member in metaType.Fields)
                    {
                        Type type = member.ItemType;
                        if (type == null) type = member.MemberType;
                        WireType defaultWireType;
                        IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, false, false);
                        if (coreSerializer == null)
                        {
                            // is an interesting type
                            int index = FindOrAddAuto(type, false, false, false);
                            if (index >= 0)
                            {
                                tmp = ((MetaType)types[index]).GetSurrogateOrBaseOrSelf(false);
                                if (!list.Contains(tmp))
                                { // could perhaps also implement as a queue, but this should work OK for sane models
                                    list.Add(tmp);
                                    CascadeDependents(list, tmp);
                                }
                            }
                        }
                    }
                }
                if (metaType.HasSubtypes)
                {
                    foreach (SubType subType in metaType.GetSubtypes())
                    {
                        tmp = subType.DerivedType.GetSurrogateOrSelf(); // note: exclude base-types!
                        if (!list.Contains(tmp))
                        {
                            list.Add(tmp);
                            CascadeDependents(list, tmp);
                        }
                    }
                }
                tmp = metaType.BaseType;
                if (tmp != null) tmp = tmp.GetSurrogateOrSelf(); // note: already walking base-types; exclude base
                if (tmp != null && !list.Contains(tmp))
                {
                    list.Add(tmp);
                    CascadeDependents(list, tmp);
                }
            }
        }
		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;
		}
Example #52
0
 public Group(int first)
 {
     this.First = first;
     this.Items = new BasicList();
 }
Example #53
0
 public override string GetSchema(Type type)
 {
     BasicList basicList = new BasicList();
     MetaType metaType = null;
     bool flag = false;
     if (type == null)
     {
         BasicList.NodeEnumerator enumerator = this.types.GetEnumerator();
         while (enumerator.MoveNext())
         {
             MetaType metaType2 = (MetaType)enumerator.Current;
             MetaType surrogateOrBaseOrSelf = metaType2.GetSurrogateOrBaseOrSelf(false);
             if (!basicList.Contains(surrogateOrBaseOrSelf))
             {
                 basicList.Add(surrogateOrBaseOrSelf);
                 this.CascadeDependents(basicList, surrogateOrBaseOrSelf);
             }
         }
     }
     else
     {
         Type underlyingType = Helpers.GetUnderlyingType(type);
         if (underlyingType != null)
         {
             type = underlyingType;
         }
         WireType wireType;
         flag = (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out wireType, false, false, false, false) != null);
         if (!flag)
         {
             int num = this.FindOrAddAuto(type, false, false, false);
             if (num < 0)
             {
                 throw new ArgumentException("The type specified is not a contract-type", "type");
             }
             metaType = ((MetaType)this.types[num]).GetSurrogateOrBaseOrSelf(false);
             basicList.Add(metaType);
             this.CascadeDependents(basicList, metaType);
         }
     }
     StringBuilder stringBuilder = new StringBuilder();
     string text = null;
     if (!flag)
     {
         IEnumerable enumerable = (metaType != null) ? basicList : this.types;
         foreach (MetaType metaType3 in enumerable)
         {
             if (!metaType3.IsList)
             {
                 string @namespace = metaType3.Type.Namespace;
                 if (!Helpers.IsNullOrEmpty(@namespace))
                 {
                     if ([email protected]("System."))
                     {
                         if (text == null)
                         {
                             text = @namespace;
                         }
                         else if (!(text == @namespace))
                         {
                             text = null;
                             break;
                         }
                     }
                 }
             }
         }
     }
     if (!Helpers.IsNullOrEmpty(text))
     {
         stringBuilder.Append("package ").Append(text).Append(';');
         Helpers.AppendLine(stringBuilder);
     }
     bool flag2 = false;
     StringBuilder stringBuilder2 = new StringBuilder();
     MetaType[] array = new MetaType[basicList.Count];
     basicList.CopyTo(array, 0);
     Array.Sort<MetaType>(array, MetaType.Comparer.Default);
     if (flag)
     {
         Helpers.AppendLine(stringBuilder2).Append("message ").Append(type.Name).Append(" {");
         MetaType.NewLine(stringBuilder2, 1).Append("optional ").Append(this.GetSchemaTypeName(type, DataFormat.Default, false, false, ref flag2)).Append(" value = 1;");
         Helpers.AppendLine(stringBuilder2).Append('}');
     }
     else
     {
         for (int i = 0; i < array.Length; i++)
         {
             MetaType metaType4 = array[i];
             if (!metaType4.IsList || metaType4 == metaType)
             {
                 metaType4.WriteSchema(stringBuilder2, 0, ref flag2);
             }
         }
     }
     if (flag2)
     {
         stringBuilder.Append("import \"bcl.proto\"; // schema for protobuf-net's handling of core .NET types");
         Helpers.AppendLine(stringBuilder);
     }
     return Helpers.AppendLine(stringBuilder.Append(stringBuilder2)).ToString();
 }
Example #54
0
 public override object Read(object value, ProtoReader source)
 {
     int field = source.FieldNumber;
     BasicList list = new BasicList();
     if (packedWireType != WireType.None && source.WireType == WireType.String)
     {
         SubItemToken token = ProtoReader.StartSubItem(source);
         while (ProtoReader.HasSubValue(packedWireType, source))
         {
             list.Add(Tail.Read(null, source));
         }
         ProtoReader.EndSubItem(token, source);
     }
     else
     { 
         do
         {
             list.Add(Tail.Read(null, source));
         } while (source.TryReadFieldHeader(field));
     }
     int oldLen = AppendToCollection ? ((value == null ? 0 : ((Array)value).Length)) : 0;
     Array result = Array.CreateInstance(itemType, oldLen + list.Count);
     if (oldLen != 0) ((Array)value).CopyTo(result, 0);
     list.CopyTo(result, oldLen);
     return result;
 }
Example #55
0
        internal void ApplyDefaultBehaviour()
        {
            if (type.BaseType != null && model.FindWithoutAdd(type.BaseType) == null &&
                GetContractFamily(type.BaseType, null) != MetaType.AttributeFamily.None)
            {
                model.FindOrAddAuto(type.BaseType, true, false, false);
            }

            object[]        typeAttribs = type.GetCustomAttributes(true);
            AttributeFamily family      = GetContractFamily(type, typeAttribs);
            bool            isEnum      = type.IsEnum;

            if (family == AttributeFamily.None && !isEnum)
            {
                return;                                            // and you'd like me to do what, exactly?
            }
            BasicList      partialIgnores = null, partialMembers = null;
            int            dataMemberOffset = 0, implicitFirstTag = 1;
            bool           inferTagByName = model.InferTagFromNameDefault;
            ImplicitFields implicitMode   = ImplicitFields.None;

            for (int i = 0; i < typeAttribs.Length; i++)
            {
                Attribute item = (Attribute)typeAttribs[i];
                if (!isEnum && item is ProtoIncludeAttribute)
                {
                    ProtoIncludeAttribute pia = (ProtoIncludeAttribute)item;
                    AddSubType(pia.Tag, pia.KnownType);
                }
                if (item is ProtoPartialIgnoreAttribute)
                {
                    if (partialIgnores == null)
                    {
                        partialIgnores = new BasicList();
                    }
                    partialIgnores.Add(((ProtoPartialIgnoreAttribute)item).MemberName);
                }
                if (!isEnum && item is ProtoPartialMemberAttribute)
                {
                    if (partialMembers == null)
                    {
                        partialMembers = new BasicList();
                    }
                    partialMembers.Add(item);
                }
                if (!isEnum && item is ProtoContractAttribute)
                {
                    ProtoContractAttribute pca = (ProtoContractAttribute)item;
                    dataMemberOffset = pca.DataMemberOffset;
                    if (pca.InferTagFromNameHasValue)
                    {
                        inferTagByName = pca.InferTagFromName;
                    }
                    implicitMode   = pca.ImplicitFields;
                    UseConstructor = !pca.SkipConstructor;
                    if (pca.ImplicitFirstTag > 0)
                    {
                        implicitFirstTag = pca.ImplicitFirstTag;
                    }
                }
            }
            if (implicitMode != ImplicitFields.None)
            {
                family &= AttributeFamily.ProtoBuf; // with implicit fields, **only** proto attributes are important
            }
            MethodInfo[] callbacks = null;

            BasicList members = new BasicList();

            foreach (MemberInfo member in type.GetMembers(isEnum ? BindingFlags.Public | BindingFlags.Static
                : BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (member.DeclaringType != type)
                {
                    continue;
                }
                if (member.IsDefined(typeof(ProtoIgnoreAttribute), true))
                {
                    continue;
                }
                if (partialIgnores != null && partialIgnores.Contains(member.Name))
                {
                    continue;
                }

                bool forced = false, isPublic, isField;
                Type effectiveType;
                switch (member.MemberType)
                {
                case MemberTypes.Property:
                    PropertyInfo property = (PropertyInfo)member;
                    effectiveType = property.PropertyType;
                    isPublic      = property.GetGetMethod(false) != null;
                    isField       = false;
                    goto ProcessMember;

                case MemberTypes.Field:
                    FieldInfo field = (FieldInfo)member;
                    effectiveType = field.FieldType;
                    isPublic      = field.IsPublic;
                    isField       = true;
ProcessMember:
                    switch (implicitMode)
                    {
                    case ImplicitFields.AllFields:
                        if (isField)
                        {
                            forced = true;
                        }
                        break;

                    case ImplicitFields.AllPublic:
                        if (isPublic)
                        {
                            forced = true;
                        }
                        break;
                    }
                    if (effectiveType.IsSubclassOf(typeof(Delegate)))
                    {
                        continue;                                                   // we just don't like delegate types ;p
                    }
                    ProtoMemberAttribute normalizedAttribute = NormalizeProtoMember(member, family, forced, isEnum, partialMembers, dataMemberOffset, inferTagByName);
                    if (normalizedAttribute != null)
                    {
                        members.Add(normalizedAttribute);
                    }
                    break;

                case MemberTypes.Method:
                    if (isEnum)
                    {
                        continue;
                    }
                    MethodInfo method        = (MethodInfo)member;
                    object[]   memberAttribs = Attribute.GetCustomAttributes(method);
                    if (memberAttribs != null && memberAttribs.Length > 0)
                    {
                        CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeSerializationAttribute", ref callbacks, 0);
                        CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterSerializationAttribute", ref callbacks, 1);
                        CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeDeserializationAttribute", ref callbacks, 2);
                        CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterDeserializationAttribute", ref callbacks, 3);
                        CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializingAttribute", ref callbacks, 4);
                        CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializedAttribute", ref callbacks, 5);
                        CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializingAttribute", ref callbacks, 6);
                        CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializedAttribute", ref callbacks, 7);
                    }
                    break;
                }
            }
            ProtoMemberAttribute[] arr = new ProtoMemberAttribute[members.Count];
            members.CopyTo(arr, 0);

            if (inferTagByName || implicitMode != ImplicitFields.None)
            {
                Array.Sort(arr);
                int nextTag = implicitFirstTag;
                foreach (ProtoMemberAttribute normalizedAttribute in arr)
                {
                    if (!normalizedAttribute.TagIsPinned) // if ProtoMember etc sets a tag, we'll trust it
                    {
                        normalizedAttribute.Rebase(nextTag++);
                    }
                }
            }

            foreach (ProtoMemberAttribute normalizedAttribute in arr)
            {
                ValueMember vm = ApplyDefaultBehaviour(isEnum, normalizedAttribute);
                if (vm != null)
                {
                    Add(vm);
                }
            }

            if (callbacks != null)
            {
                SetCallbacks(Coalesce(callbacks, 0, 4), Coalesce(callbacks, 1, 5),
                             Coalesce(callbacks, 2, 6), Coalesce(callbacks, 3, 7));
            }
        }
Example #56
0
        internal void ApplyDefaultBehaviour()
        {
            if (model.FindWithoutAdd(type.BaseType) == null &&
                GetContractFamily(type.BaseType, null) != MetaType.AttributeFamily.None)
            {
                model.FindOrAddAuto(type.BaseType, true, false, false);
            }

            object[]        typeAttribs = type.GetCustomAttributes(true);
            AttributeFamily family      = GetContractFamily(type, typeAttribs);
            bool            isEnum      = type.IsEnum;

            if (family == AttributeFamily.None && !isEnum)
            {
                return;                                            // and you'd like me to do what, exactly?
            }
            BasicList partialIgnores = null, partialMembers = null;

            for (int i = 0; i < typeAttribs.Length; i++)
            {
                if (!isEnum && typeAttribs[i] is ProtoIncludeAttribute)
                {
                    ProtoIncludeAttribute pia = (ProtoIncludeAttribute)typeAttribs[i];
                    AddSubType(pia.Tag, pia.KnownType);
                }
                if (typeAttribs[i] is ProtoPartialIgnoreAttribute)
                {
                    if (partialIgnores == null)
                    {
                        partialIgnores = new BasicList();
                    }
                    partialIgnores.Add(((ProtoPartialIgnoreAttribute)typeAttribs[i]).MemberName);
                }
                if (!isEnum && typeAttribs[i] is ProtoPartialMemberAttribute)
                {
                    if (partialMembers == null)
                    {
                        partialMembers = new BasicList();
                    }
                    partialMembers.Add(typeAttribs[i]);
                }
            }
            MethodInfo[] callbacks = null;
            foreach (MemberInfo member in type.GetMembers(isEnum ? BindingFlags.Public | BindingFlags.Static
                : BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                if (member.DeclaringType != type)
                {
                    continue;
                }
                if (member.IsDefined(typeof(ProtoIgnoreAttribute), true))
                {
                    continue;
                }
                if (partialIgnores != null && partialIgnores.Contains(member.Name))
                {
                    continue;
                }

                switch (member.MemberType)
                {
                case MemberTypes.Property:
                case MemberTypes.Field:
                    ValueMember vm = ApplyDefaultBehaviour(isEnum, family, member, partialMembers);
                    if (vm != null)
                    {
                        Add(vm);
                    }
                    break;

                case MemberTypes.Method:
                    if (isEnum)
                    {
                        continue;
                    }
                    MethodInfo method        = (MethodInfo)member;
                    object[]   memberAttribs = Attribute.GetCustomAttributes(method);
                    if (memberAttribs != null && memberAttribs.Length > 0)
                    {
                        CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeSerializationAttribute", ref callbacks, 0);
                        CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterSerializationAttribute", ref callbacks, 1);
                        CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeDeserializationAttribute", ref callbacks, 2);
                        CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterDeserializationAttribute", ref callbacks, 3);
                        CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializingAttribute", ref callbacks, 4);
                        CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializedAttribute", ref callbacks, 5);
                        CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializingAttribute", ref callbacks, 6);
                        CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializedAttribute", ref callbacks, 7);
                    }
                    break;
                }
            }
            if (callbacks != null)
            {
                SetCallbacks(callbacks[0] ?? callbacks[4], callbacks[1] ?? callbacks[5],
                             callbacks[2] ?? callbacks[6], callbacks[3] ?? callbacks[7]);
            }
        }
Example #57
0
        internal static Type GetListItemType(Type listType)
        {
            Helpers.DebugAssert(listType != null);
            if (listType == typeof(string) || listType.IsArray ||
                !typeof(IEnumerable).IsAssignableFrom(listType))
            {
                return(null);
            }

            BasicList candidates = new BasicList();

            candidates.Add(typeof(object));
            foreach (MethodInfo method in listType.GetMethods(BindingFlags.Public | BindingFlags.Instance))
            {
                if (method.Name != "Add")
                {
                    continue;
                }
                ParameterInfo[] parameters = method.GetParameters();
                if (parameters.Length == 1 && !candidates.Contains(parameters[0].ParameterType))
                {
                    candidates.Add(parameters[0].ParameterType);
                }
            }
            foreach (Type iType in listType.GetInterfaces())
            {
                if (iType.IsGenericType && iType.GetGenericTypeDefinition() == typeof(System.Collections.Generic.ICollection <>))
                {
                    Type[] iTypeArgs = iType.GetGenericArguments();
                    if (!candidates.Contains(iTypeArgs[0]))
                    {
                        candidates.Add(iTypeArgs[0]);
                    }
                }
            }
            // more convenient GetProperty overload not supported on all platforms
            foreach (PropertyInfo indexer in listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
            {
                if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType))
                {
                    continue;
                }
                ParameterInfo[] args = indexer.GetIndexParameters();
                if (args.Length != 1 || args[0].ParameterType != typeof(int))
                {
                    continue;
                }
                candidates.Add(indexer.PropertyType);
            }

            switch (candidates.Count)
            {
            case 1:
                return(null);

            case 2:
                return((Type)candidates[1]);

            case 3:
                if (CheckDictionaryAccessors((Type)candidates[1], (Type)candidates[2]))
                {
                    return((Type)candidates[1]);
                }
                if (CheckDictionaryAccessors((Type)candidates[2], (Type)candidates[1]))
                {
                    return((Type)candidates[2]);
                }
                break;
            }

            return(null);
        }
Example #58
0
        private ValueMember ApplyDefaultBehaviour(bool isEnum, AttributeFamily family, MemberInfo member, BasicList partialMembers)
        {
            if (member == null || (family == AttributeFamily.None && !isEnum))
            {
                return(null);                                                               // nix
            }
            Type effectiveType;

            switch (member.MemberType)
            {
            case MemberTypes.Field:
                effectiveType = ((FieldInfo)member).FieldType; break;

            case MemberTypes.Property:
                effectiveType = ((PropertyInfo)member).PropertyType; break;

            default:
                return(null);    // nothing doing
            }

            int    fieldNumber = 0;
            bool   isPacked    = false;
            string name        = null;
            bool   isRequired  = false;
            Type   itemType    = null;
            Type   defaultType = null;

            ResolveListTypes(effectiveType, ref itemType, ref defaultType);
            object[]   attribs = member.GetCustomAttributes(true);
            Attribute  attrib;
            DataFormat dataFormat   = DataFormat.Default;
            bool       ignore       = false;
            object     defaultValue = null;

            // implicit zero default
            switch (Type.GetTypeCode(effectiveType))
            {
            case TypeCode.Boolean: defaultValue = false; break;

            case TypeCode.Decimal: defaultValue = (decimal)0; break;

            case TypeCode.Single: defaultValue = (float)0; break;

            case TypeCode.Double: defaultValue = (double)0; break;

            case TypeCode.Byte: defaultValue = (byte)0;  break;

            case TypeCode.Char: defaultValue = (char)0; break;

            case TypeCode.Int16: defaultValue = (short)0; break;

            case TypeCode.Int32: defaultValue = (int)0; break;

            case TypeCode.Int64: defaultValue = (long)0; break;

            case TypeCode.SByte: defaultValue = (sbyte)0; break;

            case TypeCode.UInt16: defaultValue = (ushort)0; break;

            case TypeCode.UInt32: defaultValue = (uint)0; break;

            case TypeCode.UInt64: defaultValue = (ulong)0; break;

            default:
                if (effectiveType == typeof(TimeSpan))
                {
                    defaultValue = TimeSpan.Zero;
                }
                if (effectiveType == typeof(Guid))
                {
                    defaultValue = Guid.Empty;
                }
                break;
            }
            bool done = false;

            if (isEnum)
            {
                attrib = GetAttribute(attribs, "ProtoBuf.ProtoIgnoreAttribute");
                if (attrib != null)
                {
                    ignore = true;
                }
                else
                {
                    attrib      = GetAttribute(attribs, "ProtoBuf.ProtoEnumAttribute");
                    fieldNumber = Convert.ToInt32(((FieldInfo)member).GetValue(null));
                    if (attrib != null)
                    {
                        GetFieldName(ref name, attrib, "Name");
                        if ((bool)attrib.GetType().GetMethod("HasValue").Invoke(attrib, null))
                        {
                            fieldNumber = (int)GetMemberValue(attrib, "Value");
                        }
                    }
                }
                done = true;
            }
            if (!ignore && !done) // always consider ProtoMember
            {
                attrib = GetAttribute(attribs, "ProtoBuf.ProtoMemberAttribute");
                GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.ProtoIgnoreAttribute");
                if (!ignore)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Tag");
                    GetFieldName(ref name, attrib, "Name");
                    GetFieldBoolean(ref isRequired, attrib, "IsRequired");
                    GetFieldBoolean(ref isPacked, attrib, "IsPacked");
                    GetDataFormat(ref dataFormat, attrib, "DataFormat");
                    done = fieldNumber > 0;
                }

                if (!done && partialMembers != null)
                {
                    foreach (ProtoPartialMemberAttribute ppma in partialMembers)
                    {
                        if (ppma.MemberName == member.Name)
                        {
                            GetFieldNumber(ref fieldNumber, ppma, "Tag");
                            GetFieldName(ref name, ppma, "Name");
                            GetFieldBoolean(ref isRequired, ppma, "IsRequired");
                            GetFieldBoolean(ref isPacked, ppma, "IsPacked");
                            GetDataFormat(ref dataFormat, ppma, "DataFormat");
                            if (done = fieldNumber > 0)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            if (!ignore && !done && HasFamily(family, AttributeFamily.DataContractSerialier))
            {
                attrib = GetAttribute(attribs, "System.Runtime.Serialization.DataMemberAttribute");
                GetFieldNumber(ref fieldNumber, attrib, "Order");
                GetFieldName(ref name, attrib, "Name");
                GetFieldBoolean(ref isRequired, attrib, "IsRequired");
                done = fieldNumber > 0;
            }
            if (!ignore && !done && HasFamily(family, AttributeFamily.XmlSerializer))
            {
                attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlElementAttribute");
                GetIgnore(ref ignore, attrib, attribs, "System.Xml.Serialization.XmlIgnoreAttribute");
                if (!ignore)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Order");
                    GetFieldName(ref name, attrib, "ElementName");
                }
                attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlArrayAttribute");
                GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.XmlIgnoreAttribute");
                if (!ignore)
                {
                    GetFieldNumber(ref fieldNumber, attrib, "Order");
                    GetFieldName(ref name, attrib, "ElementName");
                }
                done = fieldNumber > 0;
            }
            if (!ignore && (attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null)
            {
                defaultValue = GetMemberValue(attrib, "Value");
            }
            ValueMember vm = ((isEnum || fieldNumber > 0) && !ignore)
                ? new ValueMember(model, type, fieldNumber, member, effectiveType, itemType, defaultType, dataFormat, defaultValue)
                    : null;

            if (vm != null)
            {
                PropertyInfo prop = type.GetProperty(member.Name + "Specified", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                                                     null, typeof(bool), Helpers.EmptyTypes, null);
                if (prop != null)
                {
                    vm.SetSpecified(prop.GetGetMethod(true), prop.GetSetMethod(true));
                }
                else
                {
                    MethodInfo method = type.GetMethod("ShouldSerialize" + member.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                                                       null, Helpers.EmptyTypes, null);
                    if (method != null && method.ReturnType == typeof(bool))
                    {
                        vm.SetSpecified(method, null);
                    }
                }
                if (!Helpers.IsNullOrEmpty(name))
                {
                    vm.SetName(name);
                }
                vm.IsPacked   = isPacked;
                vm.IsRequired = isRequired;
            }
            return(vm);
        }
Example #59
0
        /// <summary>
        /// Fully compiles the current model into a static-compiled serialization dll
        /// (the serialization dll still requires protobuf-net for support services).
        /// </summary>
        /// <remarks>A full compilation is restricted to accessing public types / members</remarks>
        /// <param name="name">The name of the TypeModel class to create</param>
        /// <param name="path">The path for the new dll</param>
        /// <returns>An instance of the newly created compiled type-model</returns>
        public TypeModel Compile(string name, string path)
        {
            BuildAllSerializers();
            Freeze();
            bool save = !Helpers.IsNullOrEmpty(path);

            if (Helpers.IsNullOrEmpty(name))
            {
                if (save)
                {
                    throw new ArgumentNullException("name");
                }
                name = Guid.NewGuid().ToString();
            }

            AssemblyName an = new AssemblyName();

            an.Name = name;
            AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(an,
                                                                                (save ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run)
                                                                                );

            ModuleBuilder module = save ? asm.DefineDynamicModule(name, path)
                : asm.DefineDynamicModule(name);
            Type        baseType = typeof(TypeModel);
            TypeBuilder type     = module.DefineType(name,
                                                     (baseType.Attributes & ~TypeAttributes.Abstract) | TypeAttributes.Sealed,
                                                     baseType);

            Compiler.CompilerContext ctx;

            int  index          = 0;
            bool hasInheritance = false;

            SerializerPair[] methodPairs = new SerializerPair[types.Count];
            foreach (MetaType metaType in types)
            {
                MethodBuilder writeMethod = type.DefineMethod("Write",
                                                              MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard,
                                                              typeof(void), new Type[] { metaType.Type, typeof(ProtoWriter) });

                MethodBuilder readMethod = type.DefineMethod("Read",
                                                             MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard,
                                                             metaType.Type, new Type[] { metaType.Type, typeof(ProtoReader) });

                SerializerPair pair = new SerializerPair(
                    GetKey(metaType.Type, true, false), GetKey(metaType.Type, true, true), metaType,
                    writeMethod, readMethod, writeMethod.GetILGenerator(), readMethod.GetILGenerator());
                methodPairs[index++] = pair;
                if (pair.MetaKey != pair.BaseKey)
                {
                    hasInheritance = true;
                }
            }
            if (hasInheritance)
            {
                Array.Sort(methodPairs);
            }

            for (index = 0; index < methodPairs.Length; index++)
            {
                SerializerPair pair = methodPairs[index];
                ctx = new Compiler.CompilerContext(pair.SerializeBody, true, methodPairs);
                pair.Type.Serializer.EmitWrite(ctx, Compiler.Local.InputValue);
                ctx.Return();

                ctx = new Compiler.CompilerContext(pair.DeserializeBody, true, methodPairs);
                pair.Type.Serializer.EmitRead(ctx, Compiler.Local.InputValue);
                ctx.LoadValue(Compiler.Local.InputValue);
                ctx.Return();
            }

            FieldBuilder knownTypes = type.DefineField("knownTypes", typeof(Type[]), FieldAttributes.Private | FieldAttributes.InitOnly);

            ILGenerator il = Override(type, "GetKeyImpl");

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, knownTypes);
            il.Emit(OpCodes.Ldarg_1);
            // note that Array.IndexOf is not supported under CF
            il.EmitCall(OpCodes.Callvirt, typeof(IList).GetMethod(
                            "IndexOf", new Type[] { typeof(object) }), null);
            if (hasInheritance)
            {
                il.DeclareLocal(typeof(int)); // loc-0
                il.Emit(OpCodes.Dup);
                il.Emit(OpCodes.Stloc_0);

                BasicList getKeyLabels = new BasicList();
                int       lastKey      = -1;
                for (int i = 0; i < methodPairs.Length; i++)
                {
                    if (methodPairs[i].MetaKey == methodPairs[i].BaseKey)
                    {
                        break;
                    }
                    if (lastKey == methodPairs[i].BaseKey)
                    {   // add the last label again
                        getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]);
                    }
                    else
                    {   // add a new unique label
                        getKeyLabels.Add(il.DefineLabel());
                        lastKey = methodPairs[i].BaseKey;
                    }
                }
                Label[] subtypeLabels = new Label[getKeyLabels.Count];
                getKeyLabels.CopyTo(subtypeLabels, 0);

                il.Emit(OpCodes.Switch, subtypeLabels);
                il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value
                il.Emit(OpCodes.Ret);

                lastKey = -1;
                // now output the different branches per sub-type (not derived type)
                for (int i = subtypeLabels.Length - 1; i >= 0; i--)
                {
                    if (lastKey != methodPairs[i].BaseKey)
                    {
                        lastKey = methodPairs[i].BaseKey;
                        // find the actual base-index for this base-key (i.e. the index of
                        // the base-type)
                        int keyIndex = -1;
                        for (int j = subtypeLabels.Length; j < methodPairs.Length; j++)
                        {
                            if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey)
                            {
                                keyIndex = j;
                                break;
                            }
                        }
                        il.MarkLabel(subtypeLabels[i]);
                        Compiler.CompilerContext.LoadValue(il, keyIndex);
                        il.Emit(OpCodes.Ret);
                    }
                }
            }
            else
            {
                il.Emit(OpCodes.Ret);
            }

            il  = Override(type, "Serialize");
            ctx = new Compiler.CompilerContext(il, false, methodPairs);
            // arg0 = this, arg1 = key, arg2=obj, arg3=dest
            Label[] jumpTable = new Label[types.Count];
            for (int i = 0; i < jumpTable.Length; i++)
            {
                jumpTable[i] = il.DefineLabel();
            }
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Switch, jumpTable);
            ctx.Return();
            for (int i = 0; i < jumpTable.Length; i++)
            {
                SerializerPair pair = methodPairs[i];
                il.MarkLabel(jumpTable[i]);
                il.Emit(OpCodes.Ldarg_2);
                ctx.CastFromObject(pair.Type.Type);
                il.Emit(OpCodes.Ldarg_3);
                il.EmitCall(OpCodes.Call, pair.Serialize, null);
                ctx.Return();
            }

            il  = Override(type, "Deserialize");
            ctx = new Compiler.CompilerContext(il, false, methodPairs);
            // arg0 = this, arg1 = key, arg2=obj, arg3=source
            for (int i = 0; i < jumpTable.Length; i++)
            {
                jumpTable[i] = il.DefineLabel();
            }
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Switch, jumpTable);
            ctx.LoadNullRef();
            ctx.Return();
            for (int i = 0; i < jumpTable.Length; i++)
            {
                SerializerPair pair = methodPairs[i];
                il.MarkLabel(jumpTable[i]);
                Type keyType = pair.Type.Type;
                if (keyType.IsValueType)
                {
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Ldarg_3);
                    il.EmitCall(OpCodes.Call, EmitBoxedSerializer(type, i, keyType, methodPairs), null);
                    ctx.Return();
                }
                else
                {
                    il.Emit(OpCodes.Ldarg_2);
                    ctx.CastFromObject(keyType);
                    il.Emit(OpCodes.Ldarg_3);
                    il.EmitCall(OpCodes.Call, pair.Deserialize, null);
                    ctx.Return();
                }
            }



            ConstructorBuilder ctor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Helpers.EmptyTypes);

            il = ctor.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, baseType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0]);
            il.Emit(OpCodes.Ldarg_0);
            Compiler.CompilerContext.LoadValue(il, types.Count);
            il.Emit(OpCodes.Newarr, typeof(Type));

            index = 0;
            foreach (SerializerPair pair in methodPairs)
            {
                il.Emit(OpCodes.Dup);
                Compiler.CompilerContext.LoadValue(il, index);
                il.Emit(OpCodes.Ldtoken, pair.Type.Type);
                il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
                il.Emit(OpCodes.Stelem_Ref);
                index++;
            }
            il.Emit(OpCodes.Stfld, knownTypes);
            il.Emit(OpCodes.Ret);


            Type finalType = type.CreateType();

            if (!Helpers.IsNullOrEmpty(path))
            {
                asm.Save(path);
                Helpers.DebugWriteLine("Wrote dll:" + path);
            }

            return((TypeModel)Activator.CreateInstance(finalType));
        }