示例#1
0
 /// <summary>
 /// Creates a new SubType instance.
 /// </summary>
 /// <param name="fieldNumber">The field-number that is used to encapsulate the data (as a nested
 /// message) for the derived dype.</param>
 /// <param name="derivedType">The sub-type to be considered.</param>
 public SubType(int fieldNumber, MetaType derivedType)
 {
     if (derivedType == null) throw new ArgumentNullException("derivedType");
     if (fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber");
     this.fieldNumber = fieldNumber;
     this.derivedType = derivedType;
 }
示例#2
0
 internal CallbackSet(MetaType metaType)
 {
     if (metaType == null)
     {
         throw new ArgumentNullException("metaType");
     }
     this.metaType = metaType;
 }
        private void SetBaseType(MetaType baseType)
        {
            if (baseType == null) throw new ArgumentNullException("baseType");
            if (this.baseType == baseType) return;
            if (this.baseType != null) throw new InvalidOperationException("A type can only participate in one inheritance hierarchy");

            MetaType type = baseType;
            while (type != null)
            {
                if (ReferenceEquals(type, this)) throw new InvalidOperationException("Cyclic inheritance is not allowed");
                type = type.baseType;
            }
            this.baseType = baseType;
        }
 private void WaitOnLock(MetaType type)
 {
     int opaqueToken = 0;
     try
     {
         TakeLock(ref opaqueToken);
     }
     finally
     {
         ReleaseLock(opaqueToken);
     }
 }
        /// <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 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);
                }
            }
        }
示例#7
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);
         }
     }
 }
        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());
        }
示例#9
0
 private void WaitOnLock(MetaType type)
 {
     bool lockTaken = false;
     try
     {
         TakeLock(ref lockTaken);
     }
     finally
     {
         ReleaseLock(lockTaken);
     }
 }
示例#10
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();
 }
示例#11
0
        /// <summary>

        /// Creates a new ValueMember instance

        /// </summary>

        public ValueMember(RuntimeTypeModel model, Type parentType, int fieldNumber, MemberInfo member, Type memberType, Type itemType, Type defaultType, DataFormat dataFormat, object defaultValue)

            : this(model, fieldNumber, memberType, itemType, defaultType, dataFormat)

        {
            if (member == null)
            {
                throw new ArgumentNullException("member");
            }

            if (parentType == null)
            {
                throw new ArgumentNullException("parentType");
            }

            if (fieldNumber < 1 && !Helpers.IsEnum(parentType))
            {
                throw new ArgumentOutOfRangeException("fieldNumber");
            }



            this.member = member;

            this.parentType = parentType;

            if (fieldNumber < 1 && !Helpers.IsEnum(parentType))
            {
                throw new ArgumentOutOfRangeException("fieldNumber");
            }

//#if WINRT

            if (defaultValue != null && model.MapType(defaultValue.GetType()) != memberType)

//#else

//            if (defaultValue != null && !memberType.IsInstanceOfType(defaultValue))

//#endif

            {
                defaultValue = ParseDefaultValue(memberType, defaultValue);
            }

            this.defaultValue = defaultValue;



            MetaType type = model.FindWithoutAdd(memberType);

            if (type != null)

            {
                this.asReference = type.AsReferenceDefault;
            }

            else

            { // we need to scan the hard way; can't risk recursion by fully walking it
                this.asReference = MetaType.GetAsReferenceDefault(model, memberType);
            }
        }
示例#12
0
        private MetaType RecogniseCommonTypes(Type type)
        {
            #if !NO_GENERICS
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.KeyValuePair<,>))
            {
                MetaType mt = new MetaType(this, type);

                Type surrogate = typeof (KeyValuePairSurrogate<,>).MakeGenericType(type.GetGenericArguments());

                mt.SetSurrogate(surrogate);
                mt.IncludeSerializerMethod = false;
                mt.Freeze();

                MetaType surrogateMeta = (MetaType)types[FindOrAddAuto(surrogate, true, true, true)]; // this forcibly adds it if needed
                if(surrogateMeta.IncludeSerializerMethod)
                { // don't blindly set - it might be frozen
                    surrogateMeta.IncludeSerializerMethod = false;
                }
                surrogateMeta.Freeze();
                return mt;
            }
            #endif
            return null;
        }
示例#13
0
文件: MetaType.cs 项目: helios57/anrl
        internal static MetaType GetRootType(MetaType source)
        {
            while (source.serializer != null)
            {
                MetaType tmp = source.baseType;
                if (tmp == null) return source;
                source = tmp; // else loop until we reach something that isn't generated, or is the root
            }

            // now we get into uncertain territory
            RuntimeTypeModel model = source.model;
            bool lockTaken = false;
            try {
                model.TakeLock(ref lockTaken);

                MetaType tmp;
                while ((tmp = source.baseType) != null) source = tmp;
                return source;

            } finally {
                model.ReleaseLock(lockTaken);
            }
        }
 public SerializerPair(int metaKey, int baseKey, MetaType type, MethodBuilder serialize, MethodBuilder deserialize,
     ILGenerator serializeBody, ILGenerator deserializeBody)
 {
     this.MetaKey = metaKey;
     this.BaseKey = baseKey;
     this.Serialize = serialize;
     this.Deserialize = deserialize;
     this.SerializeBody = serializeBody;
     this.DeserializeBody = deserializeBody;
     this.Type = type;
 }
示例#15
0
        internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, out WireType defaultWireType,
                                                              bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes)
        {
#if !NO_GENERICS
            {
                Type tmp = Helpers.GetUnderlyingType(type);
                if (tmp != null)
                {
                    type = tmp;
                }
            }
#endif
            if (Helpers.IsEnum(type))
            {
                if (allowComplexTypes && model != null)
                {
                    // need to do this before checking the typecode; an int enum will report Int32 etc
                    defaultWireType = WireType.Variant;
                    return(new EnumSerializer(type, model.GetEnumMap(type)));
                }
                else
                { // enum is fine for adding as a meta-type
                    defaultWireType = WireType.None;
                    return(null);
                }
            }
            ProtoTypeCode code = Helpers.GetTypeCode(type);
            switch (code)
            {
            case ProtoTypeCode.Int32:
                defaultWireType = GetIntWireType(dataFormat, 32);
                return(new Int32Serializer(model));

            case ProtoTypeCode.UInt32:
                defaultWireType = GetIntWireType(dataFormat, 32);
                return(new UInt32Serializer(model));

            case ProtoTypeCode.Int64:
                defaultWireType = GetIntWireType(dataFormat, 64);
                return(new Int64Serializer(model));

            case ProtoTypeCode.UInt64:
                defaultWireType = GetIntWireType(dataFormat, 64);
                return(new UInt64Serializer(model));

            case ProtoTypeCode.String:
                defaultWireType = WireType.String;
                if (asReference)
                {
                    return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference));
                }
                return(new StringSerializer(model));

            case ProtoTypeCode.Single:
                defaultWireType = WireType.Fixed32;
                return(new SingleSerializer(model));

            case ProtoTypeCode.Double:
                defaultWireType = WireType.Fixed64;
                return(new DoubleSerializer(model));

            case ProtoTypeCode.Boolean:
                defaultWireType = WireType.Variant;
                return(new BooleanSerializer(model));

            case ProtoTypeCode.DateTime:
                defaultWireType = GetDateTimeWireType(dataFormat);
                return(new DateTimeSerializer(model));

            case ProtoTypeCode.Decimal:
                defaultWireType = WireType.String;
                return(new DecimalSerializer(model));

            case ProtoTypeCode.Byte:
                defaultWireType = GetIntWireType(dataFormat, 32);
                return(new ByteSerializer(model));

            case ProtoTypeCode.SByte:
                defaultWireType = GetIntWireType(dataFormat, 32);
                return(new SByteSerializer(model));

            case ProtoTypeCode.Char:
                defaultWireType = WireType.Variant;
                return(new CharSerializer(model));

            case ProtoTypeCode.Int16:
                defaultWireType = GetIntWireType(dataFormat, 32);
                return(new Int16Serializer(model));

            case ProtoTypeCode.UInt16:
                defaultWireType = GetIntWireType(dataFormat, 32);
                return(new UInt16Serializer(model));

            case ProtoTypeCode.TimeSpan:
                defaultWireType = GetDateTimeWireType(dataFormat);
                return(new TimeSpanSerializer(model));

            case ProtoTypeCode.Guid:
                defaultWireType = WireType.String;
                return(new GuidSerializer(model));

            case ProtoTypeCode.Uri:
                defaultWireType = WireType.String;
                return(new StringSerializer(model));

            case ProtoTypeCode.ByteArray:
                defaultWireType = WireType.String;
                return(new BlobSerializer(model, overwriteList));

            case ProtoTypeCode.Type:
                defaultWireType = WireType.String;
                return(new SystemTypeSerializer(model));
            }
            IProtoSerializer parseable = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null;
            if (parseable != null)
            {
                defaultWireType = WireType.String;
                return(parseable);
            }
            if (allowComplexTypes && model != null)
            {
                int key = model.GetKey(type, false, true);
                if (asReference || dynamicType)
                {
                    defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String;
                    BclHelpers.NetObjectOptions options = BclHelpers.NetObjectOptions.None;
                    if (asReference)
                    {
                        options |= BclHelpers.NetObjectOptions.AsReference;
                    }
                    if (dynamicType)
                    {
                        options |= BclHelpers.NetObjectOptions.DynamicType;
                    }
                    if (key >= 0)
                    { // exists
                        if (asReference && Helpers.IsValueType(type))
                        {
                            string message = "AsReference cannot be used with value-types";

                            if (type.Name == "KeyValuePair`2")
                            {
                                message += "; please see http://stackoverflow.com/q/14436606/";
                            }
                            else
                            {
                                message += ": " + type.FullName;
                            }
                            throw new InvalidOperationException(message);
                        }
                        MetaType meta = model[type];
                        if (asReference && meta.IsAutoTuple)
                        {
                            options |= BclHelpers.NetObjectOptions.LateSet;
                        }
                        if (meta.UseConstructor)
                        {
                            options |= BclHelpers.NetObjectOptions.UseConstructor;
                        }
                    }
                    return(new NetObjectSerializer(model, type, key, options));
                }
                if (key >= 0)
                {
                    defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String;
                    return(new SubItemSerializer(type, key, model[type], true));
                }
            }
            defaultWireType = WireType.None;
            return(null);
        }
示例#16
0
 internal TypeAddedEventArgs(MetaType metaType)
 {
     MetaType = metaType;
     ApplyDefaultBehaviour = true;
 }
示例#17
0
 internal CallbackSet(MetaType metaType)
 {
     this.metaType = metaType ?? throw new ArgumentNullException(nameof(metaType));
 }
示例#18
0
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);// check nobody is still adding this type
                var member = backingMember ?? originalMember;
                IProtoSerializer ser;
                if (IsMap)
                {
                    ResolveMapTypes(out var dictionaryType, out var keyType, out var valueType);

                    if (dictionaryType == null)
                    {
                        throw new InvalidOperationException("Unable to resolve map type for type: " + memberType.FullName);
                    }
                    var concreteType = defaultType;
                    if (concreteType == null && Helpers.IsClass(memberType))
                    {
                        concreteType = memberType;
                    }
                    var keySer = TryGetCoreSerializer(model, MapKeyFormat, keyType, out var keyWireType, false, false, false, false);
                    if (!AsReference)
                    {
                        AsReference = MetaType.GetAsReferenceDefault(model, valueType);
                    }
                    var valueSer = TryGetCoreSerializer(model, MapValueFormat, valueType, out var valueWireType, AsReference, DynamicType, false, true);
#if PROFILE259
                    IEnumerable <ConstructorInfo> ctors = typeof(MapDecorator <, ,>).MakeGenericType(new Type[] { dictionaryType, keyType, valueType }).GetTypeInfo().DeclaredConstructors;
                    if (ctors.Count() != 1)
                    {
                        throw new InvalidOperationException("Unable to resolve MapDecorator constructor");
                    }
                    ser = (IProtoSerializer)ctors.First().Invoke(new object[] { model, concreteType, keySer, valueSer, fieldNumber,
                                                                                DataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String, keyWireType, valueWireType, OverwriteList });
#else
                    var ctors = typeof(MapDecorator <, ,>).MakeGenericType(new Type[] { dictionaryType, keyType, valueType }).GetConstructors(
                        BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                    if (ctors.Length != 1)
                    {
                        throw new InvalidOperationException("Unable to resolve MapDecorator constructor");
                    }
                    ser = (IProtoSerializer)ctors[0].Invoke(new object[] { model, concreteType, keySer, valueSer, fieldNumber,
                                                                           DataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String, keyWireType, valueWireType, OverwriteList });
#endif
                }
                else
                {
                    WireType wireType;
                    Type     finalType = itemType == null ? memberType : itemType;
                    ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, AsReference, DynamicType, OverwriteList, true);
                    if (ser == null)
                    {
                        throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                    }

                    // apply tags
                    if (itemType != null && SupportNull)
                    {
                        if (IsPacked)
                        {
                            throw new NotSupportedException("Packed encodings cannot support null values");
                        }
                        ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser);
                        ser = new NullDecorator(model, ser);
                        ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser);
                    }
                    else
                    {
                        ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                    }
                    // apply lists if appropriate
                    if (itemType != null)
                    {
#if NO_GENERICS
                        Type underlyingItemType = itemType;
#else
                        Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType;
#endif
                        Helpers.DebugAssert(underlyingItemType == ser.ExpectedType ||
                                            (ser.ExpectedType == model.MapType(typeof(object)) && !Helpers.IsValueType(underlyingItemType))
                                            , "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
                        if (memberType.IsArray)
                        {
                            ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull);
                        }
                        else
                        {
                            ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull);
                        }
                    }
                    else if (defaultValue != null && !IsRequired && getSpecified == null)
                    {   // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue,
                        // as does "IsRequired"
                        ser = new DefaultValueDecorator(model, defaultValue, ser);
                    }
                    if (memberType == model.MapType(typeof(Uri)))
                    {
                        ser = new UriDecorator(model, ser);
                    }
#if PORTABLE
                    else if (memberType.FullName == typeof(Uri).FullName)
                    {
                        // In PCLs, the Uri type may not match (WinRT uses Internal/Uri, .Net uses System/Uri)
                        ser = new ReflectedUriDecorator(memberType, model, ser);
                    }
#endif
                }
                if (member != null)
                {
                    PropertyInfo prop = member as PropertyInfo;
                    if (prop != null)
                    {
                        ser = new PropertyDecorator(model, parentType, (PropertyInfo)member, ser);
                    }
                    else
                    {
                        FieldInfo fld = member as FieldInfo;
                        if (fld != null)
                        {
                            ser = new FieldDecorator(parentType, (FieldInfo)member, ser);
                        }
                        else
                        {
                            throw new InvalidOperationException();
                        }
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
示例#19
0
        internal int FindOrAddAuto(Type type, bool demand, bool addWithContractOnly, bool addEvenIfAutoDisabled)
        {
            TypeFinder predicate = new TypeFinder(type);
            int        key       = types.IndexOf(predicate);
            MetaType   metaType;

            if (key >= 0 && (metaType = ((MetaType)types[key])).Pending)
            {
                WaitOnLock(metaType);
            }
            if (key < 0)
            {
                // check for proxy types
                Type underlyingType = ResolveProxies(type);
                if (underlyingType != null)
                {
                    predicate = new TypeFinder(underlyingType);
                    key       = types.IndexOf(predicate);
                    type      = underlyingType; // if new added, make it reflect the underlying type
                }
            }

            if (key < 0)
            {
                bool lockTaken = false;
                try
                {
                    TakeLock(ref lockTaken);
                    // try to recognise a few familiar patterns...
                    if ((metaType = RecogniseCommonTypes(type)) == null)
                    { // otherwise, check if it is a contract
                        bool shouldAdd = autoAddMissingTypes || addEvenIfAutoDisabled;
                        if (!shouldAdd || (
                                addWithContractOnly && MetaType.GetContractFamily(type, null) == MetaType.AttributeFamily.None)
                            )
                        {
                            if (demand)
                            {
                                ThrowUnexpectedType(type);
                            }
                            return(key);
                        }
                        metaType = Create(type);
                    }
                    metaType.Pending = true;
                    bool weAdded = false;

                    // double-checked
                    int winner = types.IndexOf(predicate);
                    if (winner < 0)
                    {
                        ThrowIfFrozen();
                        key     = types.Add(metaType);
                        weAdded = true;
                    }
                    else
                    {
                        key = winner;
                    }
                    if (weAdded)
                    {
                        metaType.ApplyDefaultBehaviour();
                        metaType.Pending = false;
                    }
                }
                finally
                {
                    ReleaseLock(lockTaken);
                }
            }
            return(key);
        }
 /// <summary>
 /// Import framework options from an existing type
 /// </summary>
 public void SetFrameworkOptions(MetaType from)
 {
     if (from == null) throw new ArgumentNullException("from");
     AttributeMap[] attribs = AttributeMap.Create(from.Model, from.Type.Assembly);
     foreach (AttributeMap attrib in attribs)
     {
         if (attrib.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute")
         {
             object tmp;
             if (attrib.TryGet("FrameworkName", out tmp)) TargetFrameworkName = (string)tmp;
             if (attrib.TryGet("FrameworkDisplayName", out tmp)) TargetFrameworkDisplayName = (string)tmp;
             break;
         }
     }
 }
        private MetaType RecogniseCommonTypes(Type type)
        {
#if !NO_GENERICS
            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.KeyValuePair<,>))
            {
                MetaType mt = new MetaType(this, type);
//#pragma warning disable 618 // we're *allowed* to do this; user code isn't (we might roll this as a bespoke serializer rather than a surrogate at some point)
                Type surrogate = typeof (KeyValuePairSurrogate<,>).MakeGenericType(type.GetGenericArguments());
//#pragma warning restore 618
                mt.SetSurrogate(surrogate);
                mt.IncludeSerializerMethod = false;
                mt.Freeze();

                MetaType surrogateMeta = (MetaType)types[FindOrAddAuto(surrogate, true, true, true)]; // this forcibly adds it if needed
                if(surrogateMeta.IncludeSerializerMethod)
                { // don't blindly set - it might be frozen
                    surrogateMeta.IncludeSerializerMethod = false;
                }
                surrogateMeta.Freeze();
                return mt;
            }
#endif
            return null;
        }