Example #1
0
            void parse()
            {
                MemberInfo[] mbs = type.GetMembers();
                foreach (MemberInfo mb in mbs)
                {
                    PBMember pbm = new PBMember();
                    //获取所有ProtoMemberAttribute属性(PB字段)
                    ProtoMemberAttribute attr = Attribute.GetCustomAttribute(mb, typeof(ProtoMemberAttribute)) as ProtoMemberAttribute;
                    if (attr != null)
                    {
                        pbm.name    = attr.Name;
                        pbm.tag     = attr.Tag;
                        pbm.datafmt = attr.DataFormat;
                        DefaultValueAttribute dva = Attribute.GetCustomAttribute(mb, typeof(DefaultValueAttribute)) as DefaultValueAttribute;
                        if (dva != null)
                        {
                            pbm.defaultVaule = dva.Value;
                        }
                        pbm.isRequire      = attr.IsRequired;
                        pbm.isPacked       = attr.IsPacked;
                        pbm.isOverrideList = attr.OverwriteList;
                    }

                    ProtoEnumAttribute pea = Attribute.GetCustomAttribute(mb, typeof(ProtoEnumAttribute)) as ProtoEnumAttribute;
                    if (pea != null)
                    {
                        pbm.name         = pea.Name;
                        pbm.defaultVaule = pea.Value;
                    }

                    if (attr == null && pea == null)
                    {
                        continue;
                    }

                    Type memberType = null;
                    switch (mb.MemberType)
                    {
                    case MemberTypes.Field:
                        memberType = ((FieldInfo)mb).FieldType; break;

                    case MemberTypes.Property:
                        memberType = ((PropertyInfo)mb).PropertyType; break;

                    default:
                        throw new NotSupportedException(mb.MemberType.ToString());
                    }
                    pbm.valueType = memberType;
                    addMember(pbm);
                }
            }
Example #2
0
        public ProtoJsonPropertyAccessor(PropertyInfo p) : base(p)
        {
            TypeInfo ti = p.PropertyType.GetTypeInfo();

            IsList = p.PropertyType != typeof(string) && typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(ti);

            ProtoMemberAttribute attribute = p.GetCustomAttribute <ProtoMemberAttribute>();

            IsOptional = attribute.Optional;
            Position   = attribute.Position;

            if (IsList)
            {
                UnderlyingType = ti.GenericTypeArguments.FirstOrDefault();
                ti             = UnderlyingType.GetTypeInfo();
            }

            IsProtoContract = ti.IsDefined(typeof(ProtoContractAttribute), false);
            IsEnum          = ti.IsEnum;
        }
Example #3
0
        public ProtoJsonPropertyAccessor(PropertyInfo p) : base(p)
        {
            // after base is initialized GenericType contains
            TypeInfo ti = GenericType.GetTypeInfo();

            ProtoMemberAttribute attribute = p.GetCustomAttribute <ProtoMemberAttribute>();

            if (attribute != null)
            {
                IsOptional = attribute.Optional;
                Position   = attribute.Position;
            }

            ProtoJsonType = AttributeTypeEnum.Value;

            if (IsEnum)
            {
                ProtoJsonType = AttributeTypeEnum.Enum;
            }
            else if (ti.IsDefined(typeof(ProtoContractAttribute), false))
            {
                ProtoJsonType = AttributeTypeEnum.ProtoContract;
            }
        }
    private static string GenDeserializeScript(Type type)
    {
        string deserCode = DESERIALIZE_FUNC_TEMP;

        deserCode = deserCode.Replace("$CreateInstance$", type.IsAbstract ?  "" : INSTANCE_TEMP);
        deserCode = deserCode.Replace("$Type$", GetTypeFullName(type));

        StringBuilder stringBuilder = new StringBuilder();

        /* 多态 */
        ProtoIncludeAttribute[] includes = type.GetAttributes <ProtoIncludeAttribute>();
        foreach (var include in includes)
        {
            string includeCode = DYNAMIC_TEMP;
            includeCode = includeCode.Replace("$CaseNum$", include.Tag.ToString());
            includeCode = includeCode.Replace("$DerivedName$", include.KnownType.Name);
            includeCode = includeCode.Replace("$DerivedType$", GetTypeFullName(include.KnownType));

            stringBuilder.Append(includeCode);
        }


        /* 成员 */
        MemberInfo[] memberInfos = type.GetMembers(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
        foreach (MemberInfo memberInfo in memberInfos)
        {
            if (memberInfo.DeclaringType != type)
            {
                continue;
            }
            if (memberInfo.IsDefined(typeof(ProtoIgnoreAttribute), true))
            {
                continue;
            }

            ProtoMemberAttribute memberAttr = memberInfo.GetAttribute <ProtoMemberAttribute>();
            if (memberAttr == null)
            {
                continue;
            }

            PropertyInfo propertyInfo;
            FieldInfo    fieldInfo;

            Type memberType = null;

            if ((propertyInfo = memberInfo as PropertyInfo) != null)
            {
                memberType = propertyInfo.PropertyType;
            }
            else if ((fieldInfo = memberInfo as FieldInfo) != null)
            {
                memberType = fieldInfo.FieldType;
            }

            if (memberType == null)
            {
                continue;
            }

            string caseCode = CASE_TEMP;
            caseCode = caseCode.Replace("$CaseNum$", memberAttr.Tag.ToString());

            ProtoSupportSetAttribute supportSetAttribute = memberInfo.GetAttribute <ProtoSupportSetAttribute>();
            if (supportSetAttribute != null)
            {
                caseCode = caseCode.Replace("$WriteField$", WRITE_BYFUN_TEMP);
                caseCode = caseCode.Replace("$Value$", supportSetAttribute.FunctionParam);
                caseCode = caseCode.Replace("$MemberName$", supportSetAttribute.FunctionName);
                caseCode = caseCode.Replace("$Param$", VALUE_TEMP);
                caseCode = caseCode.Replace("$ValueType$", GetTypeFullName(memberType));
            }
            else
            {
                caseCode = caseCode.Replace("$WriteField$", WRITE_BYFIELD_TEMP);
                caseCode = caseCode.Replace("$Value$", VALUE_TEMP);
                caseCode = caseCode.Replace("$MemberName$", memberInfo.Name);
                caseCode = caseCode.Replace("$ValueType$", GetTypeFullName(memberType));
            }



            string handleCode = GenTypeReadCode(memberInfo, memberType, memberInfo.Name, memberAttr.Tag);
            if (!string.IsNullOrEmpty(handleCode))
            {
                if (!type.IsValueType && !type.IsAbstract)
                {
                    handleCode = CREATE_OBJ + handleCode;
                    handleCode = handleCode.Replace("$ObjValue$", GetTypeFullName(type));
                }

                stringBuilder.Append(caseCode.Replace("$CaseHandle$", handleCode));
            }
        }
        return(deserCode.Replace("$CaseContent$", stringBuilder.ToString()));
    }
Example #5
0
        private ValueMember ApplyDefaultBehaviour(bool isEnum, ProtoMemberAttribute normalizedAttribute)
        {
            MemberInfo member;
            if (normalizedAttribute == null || (member = normalizedAttribute.Member) == null) 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
            }

            Type itemType = null;
            Type defaultType = null;
            ResolveListTypes(effectiveType, ref itemType, ref defaultType);
            object[] attribs = member.GetCustomAttributes(true);
            Attribute attrib;

            object defaultValue = null;
            // implicit zero default
            if (model.UseImplicitZeroDefaults)
            {
                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;
                }
            }
            if ((attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null)
            {
                defaultValue = GetMemberValue(attrib, "Value");
            }
            ValueMember vm = ((isEnum || normalizedAttribute.Tag > 0))
                ? new ValueMember(model, type, normalizedAttribute.Tag, member, effectiveType, itemType, defaultType, normalizedAttribute.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(normalizedAttribute.Name)) vm.SetName(normalizedAttribute.Name);
                vm.IsPacked = normalizedAttribute.IsPacked;
                vm.IsRequired = normalizedAttribute.IsRequired;
                vm.OverwriteList = normalizedAttribute.OverwriteList;
                vm.AsReference = normalizedAttribute.AsReference;
                vm.DynamicType = normalizedAttribute.DynamicType;
            }
            return vm;
        }
Example #6
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 #7
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 #8
0
        private ValueMember ApplyDefaultBehaviour(bool isEnum, ProtoMemberAttribute normalizedAttribute)
        {
            MemberInfo member;

            if (normalizedAttribute == null || (member = normalizedAttribute.Member) == null)
            {
                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
            }


            Type itemType    = null;
            Type defaultType = null;

            ResolveListTypes(effectiveType, ref itemType, ref defaultType);
            object[]  attribs = member.GetCustomAttributes(true);
            Attribute attrib;

            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;
            }

            if ((attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null)
            {
                defaultValue = GetMemberValue(attrib, "Value");
            }
            ValueMember vm = ((isEnum || normalizedAttribute.Tag > 0))
                ? new ValueMember(model, type, normalizedAttribute.Tag, member, effectiveType, itemType, defaultType, normalizedAttribute.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(normalizedAttribute.Name))
                {
                    vm.SetName(normalizedAttribute.Name);
                }
                vm.IsPacked      = normalizedAttribute.IsPacked;
                vm.IsRequired    = normalizedAttribute.IsRequired;
                vm.OverwriteList = normalizedAttribute.OverwriteList;
                vm.AsReference   = normalizedAttribute.AsReference;
                vm.DynamicType   = normalizedAttribute.DynamicType;
            }
            return(vm);
        }
Example #9
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 #10
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 #11
0
        /// <summary>
        /// 增加一个类型,使protobuf支持该类型的父类(仅带有ProtoContract的父类)中所有需要序列化的属性
        /// </summary>
        /// <param name="type">需要被支持继承的类</param>
        public static void AddType(Type type)
        {
            if (type == null)
            {
                return;
            }
            if (!type.IsDefined(type_proto_contract, false))
            {
                return;
            }
            if (added_types.ContainsKey(type))
            {
                return;
            }
            added_types.Add(type, (byte)0);
            Type             bt    = type;
            RuntimeTypeModel model = RuntimeTypeModel.Default;

            MemberInfo[] ms = bt.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            for (int i = 0, imax = ms.Length; i < imax; i++)
            {
                MemberInfo mi = ms[i];
                if (!Attribute.IsDefined(mi, typeof(ProtoMemberAttribute)))
                {
                    continue;
                }
                Type mt = null;
                switch (mi.MemberType)
                {
                case MemberTypes.Field:
                    mt = (mi as FieldInfo).FieldType;
                    break;

                case MemberTypes.Property:
                    mt = (mi as PropertyInfo).PropertyType;
                    break;
                }
                if (mt == null)
                {
                    continue;
                }
                if (mt.IsGenericType)
                {
                    Type[] gt = mt.GetGenericArguments();
                    for (int j = 0, jmax = gt.Length; j < jmax; j++)
                    {
                        AddType(gt[j]);
                    }
                }
                if (mt.IsArray)
                {
                    AddType(mt.GetElementType());
                }
                AddType(mt);
            }
            while (true)
            {
                bt = bt.BaseType;
                if (bt == null || bt == type_obj)
                {
                    break;
                }
                if (!bt.IsDefined(type_proto_contract, false))
                {
                    continue;
                }
                ms = bt.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
                for (int i = 0, imax = ms.Length; i < imax; i++)
                {
                    MemberInfo mi = ms[i];
                    //if (mi.DeclaringType != bt) { continue; }
                    ProtoMemberAttribute pm = Attribute.GetCustomAttribute(mi, typeof(ProtoMemberAttribute)) as ProtoMemberAttribute;
                    if (pm == null)
                    {
                        continue;
                    }
                    try
                    {
                        model[type].Add(pm.Tag, mi.Name);
                    }
                    catch { }
                    //UnityEngine.Debug.LogWarning(type + "  " + pm.Tag + "  " +mi.Name);
                }
            }
        }
Example #12
0
 public void FillFromAttribute(ProtoMemberAttribute pma)
 {
     Tag     = pma.Tag;
     Options = pma.Options;
 }