internal static AttributeFamily GetContractFamily(Type type, object[] attributes) { AttributeFamily family = AttributeFamily.None; if (attributes == null) { attributes = type.GetCustomAttributes(false); } for (int i = 0; i < attributes.Length; i++) { switch (attributes[i].GetType().FullName) { case "ProtoBuf.ProtoContractAttribute": bool tmp = false; GetFieldBoolean(ref tmp, (Attribute)attributes[i], "UseProtoMembersOnly"); if (tmp) { return(AttributeFamily.ProtoBuf); } family |= AttributeFamily.ProtoBuf; break; case "System.Xml.Serialization.XmlTypeAttribute": family |= AttributeFamily.XmlSerializer; break; case "System.Runtime.Serialization.DataContractAttribute": family |= AttributeFamily.DataContractSerialier; break; } } return(family); }
internal static AttributeFamily GetContractFamily(Type type, object[] attributes) { AttributeFamily family = AttributeFamily.None; if (attributes == null) { attributes = type.GetCustomAttributes(true); } for (int i = 0; i < attributes.Length; i++) { switch (attributes[i].GetType().FullName) { case "ProtoBuf.ProtoContractAttribute": family |= AttributeFamily.ProtoBuf; break; case "System.Xml.Serialization.XmlTypeAttribute": family |= AttributeFamily.XmlSerializer; break; case "System.Runtime.Serialization.DataContractAttribute": family |= AttributeFamily.DataContractSerialier; break; } } return(family); }
private ValueMember ApplyDefaultBehaviour(bool isEnum, AttributeFamily family, MemberInfo member, BasicList partialMembers) { if (member == null || (family == AttributeFamily.None && !isEnum)) { return(null); // nix } Type effectiveType; switch (member.MemberType) { case MemberTypes.Field: effectiveType = ((FieldInfo)member).FieldType; break; case MemberTypes.Property: effectiveType = ((PropertyInfo)member).PropertyType; break; default: return(null); // nothing doing } int fieldNumber = 0; bool isPacked = false; string name = null; bool isRequired = false; Type itemType = null; Type defaultType = null; ResolveListTypes(effectiveType, ref itemType, ref defaultType); object[] attribs = member.GetCustomAttributes(true); Attribute attrib; DataFormat dataFormat = DataFormat.Default; bool ignore = false; object defaultValue = null; // implicit zero default switch (Type.GetTypeCode(effectiveType)) { case TypeCode.Boolean: defaultValue = false; break; case TypeCode.Decimal: defaultValue = (decimal)0; break; case TypeCode.Single: defaultValue = (float)0; break; case TypeCode.Double: defaultValue = (double)0; break; case TypeCode.Byte: defaultValue = (byte)0; break; case TypeCode.Char: defaultValue = (char)0; break; case TypeCode.Int16: defaultValue = (short)0; break; case TypeCode.Int32: defaultValue = (int)0; break; case TypeCode.Int64: defaultValue = (long)0; break; case TypeCode.SByte: defaultValue = (sbyte)0; break; case TypeCode.UInt16: defaultValue = (ushort)0; break; case TypeCode.UInt32: defaultValue = (uint)0; break; case TypeCode.UInt64: defaultValue = (ulong)0; break; default: if (effectiveType == typeof(TimeSpan)) { defaultValue = TimeSpan.Zero; } if (effectiveType == typeof(Guid)) { defaultValue = Guid.Empty; } break; } bool done = false; if (isEnum) { attrib = GetAttribute(attribs, "ProtoBuf.ProtoIgnoreAttribute"); if (attrib != null) { ignore = true; } else { attrib = GetAttribute(attribs, "ProtoBuf.ProtoEnumAttribute"); fieldNumber = Convert.ToInt32(((FieldInfo)member).GetValue(null)); if (attrib != null) { GetFieldName(ref name, attrib, "Name"); if ((bool)attrib.GetType().GetMethod("HasValue").Invoke(attrib, null)) { fieldNumber = (int)GetMemberValue(attrib, "Value"); } } } done = true; } if (!ignore && !done) // always consider ProtoMember { attrib = GetAttribute(attribs, "ProtoBuf.ProtoMemberAttribute"); GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.ProtoIgnoreAttribute"); if (!ignore) { GetFieldNumber(ref fieldNumber, attrib, "Tag"); GetFieldName(ref name, attrib, "Name"); GetFieldBoolean(ref isRequired, attrib, "IsRequired"); GetFieldBoolean(ref isPacked, attrib, "IsPacked"); GetDataFormat(ref dataFormat, attrib, "DataFormat"); done = fieldNumber > 0; } if (!done && partialMembers != null) { foreach (ProtoPartialMemberAttribute ppma in partialMembers) { if (ppma.MemberName == member.Name) { GetFieldNumber(ref fieldNumber, ppma, "Tag"); GetFieldName(ref name, ppma, "Name"); GetFieldBoolean(ref isRequired, ppma, "IsRequired"); GetFieldBoolean(ref isPacked, ppma, "IsPacked"); GetDataFormat(ref dataFormat, ppma, "DataFormat"); if (done = fieldNumber > 0) { break; } } } } } if (!ignore && !done && HasFamily(family, AttributeFamily.DataContractSerialier)) { attrib = GetAttribute(attribs, "System.Runtime.Serialization.DataMemberAttribute"); GetFieldNumber(ref fieldNumber, attrib, "Order"); GetFieldName(ref name, attrib, "Name"); GetFieldBoolean(ref isRequired, attrib, "IsRequired"); done = fieldNumber > 0; } if (!ignore && !done && HasFamily(family, AttributeFamily.XmlSerializer)) { attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlElementAttribute"); GetIgnore(ref ignore, attrib, attribs, "System.Xml.Serialization.XmlIgnoreAttribute"); if (!ignore) { GetFieldNumber(ref fieldNumber, attrib, "Order"); GetFieldName(ref name, attrib, "ElementName"); } attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlArrayAttribute"); GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.XmlIgnoreAttribute"); if (!ignore) { GetFieldNumber(ref fieldNumber, attrib, "Order"); GetFieldName(ref name, attrib, "ElementName"); } done = fieldNumber > 0; } if (!ignore && (attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null) { defaultValue = GetMemberValue(attrib, "Value"); } ValueMember vm = ((isEnum || fieldNumber > 0) && !ignore) ? new ValueMember(model, type, fieldNumber, member, effectiveType, itemType, defaultType, dataFormat, defaultValue) : null; if (vm != null) { PropertyInfo prop = type.GetProperty(member.Name + "Specified", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, typeof(bool), Helpers.EmptyTypes, null); if (prop != null) { vm.SetSpecified(prop.GetGetMethod(true), prop.GetSetMethod(true)); } else { MethodInfo method = type.GetMethod("ShouldSerialize" + member.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Helpers.EmptyTypes, null); if (method != null && method.ReturnType == typeof(bool)) { vm.SetSpecified(method, null); } } if (!Helpers.IsNullOrEmpty(name)) { vm.SetName(name); } vm.IsPacked = isPacked; vm.IsRequired = isRequired; } return(vm); }
private static bool HasFamily(AttributeFamily value, AttributeFamily required) { return((value & required) == required); }
internal void ApplyDefaultBehaviour() { if (model.FindWithoutAdd(type.BaseType) == null && GetContractFamily(type.BaseType, null) != MetaType.AttributeFamily.None) { model.FindOrAddAuto(type.BaseType, true, false, false); } object[] typeAttribs = type.GetCustomAttributes(true); AttributeFamily family = GetContractFamily(type, typeAttribs); bool isEnum = type.IsEnum; if (family == AttributeFamily.None && !isEnum) { return; // and you'd like me to do what, exactly? } BasicList partialIgnores = null, partialMembers = null; for (int i = 0; i < typeAttribs.Length; i++) { if (!isEnum && typeAttribs[i] is ProtoIncludeAttribute) { ProtoIncludeAttribute pia = (ProtoIncludeAttribute)typeAttribs[i]; AddSubType(pia.Tag, pia.KnownType); } if (typeAttribs[i] is ProtoPartialIgnoreAttribute) { if (partialIgnores == null) { partialIgnores = new BasicList(); } partialIgnores.Add(((ProtoPartialIgnoreAttribute)typeAttribs[i]).MemberName); } if (!isEnum && typeAttribs[i] is ProtoPartialMemberAttribute) { if (partialMembers == null) { partialMembers = new BasicList(); } partialMembers.Add(typeAttribs[i]); } } MethodInfo[] callbacks = null; foreach (MemberInfo member in type.GetMembers(isEnum ? BindingFlags.Public | BindingFlags.Static : BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (member.DeclaringType != type) { continue; } if (member.IsDefined(typeof(ProtoIgnoreAttribute), true)) { continue; } if (partialIgnores != null && partialIgnores.Contains(member.Name)) { continue; } switch (member.MemberType) { case MemberTypes.Property: case MemberTypes.Field: ValueMember vm = ApplyDefaultBehaviour(isEnum, family, member, partialMembers); if (vm != null) { Add(vm); } break; case MemberTypes.Method: if (isEnum) { continue; } MethodInfo method = (MethodInfo)member; object[] memberAttribs = Attribute.GetCustomAttributes(method); if (memberAttribs != null && memberAttribs.Length > 0) { CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeSerializationAttribute", ref callbacks, 0); CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterSerializationAttribute", ref callbacks, 1); CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeDeserializationAttribute", ref callbacks, 2); CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterDeserializationAttribute", ref callbacks, 3); CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializingAttribute", ref callbacks, 4); CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializedAttribute", ref callbacks, 5); CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializingAttribute", ref callbacks, 6); CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializedAttribute", ref callbacks, 7); } break; } } if (callbacks != null) { SetCallbacks(callbacks[0] ?? callbacks[4], callbacks[1] ?? callbacks[5], callbacks[2] ?? callbacks[6], callbacks[3] ?? callbacks[7]); } }
private ValueMember ApplyDefaultBehaviour(bool isEnum, AttributeFamily family, MemberInfo member, BasicList partialMembers) { if (member == null || (family == AttributeFamily.None && !isEnum)) return null; // nix Type effectiveType; switch (member.MemberType) { case MemberTypes.Field: effectiveType = ((FieldInfo)member).FieldType; break; case MemberTypes.Property: effectiveType = ((PropertyInfo)member).PropertyType; break; default: return null; // nothing doing } int fieldNumber = 0; bool isPacked = false; string name = null; bool isRequired = false; Type itemType = null; Type defaultType = null; ResolveListTypes(effectiveType, ref itemType, ref defaultType); object[] attribs = member.GetCustomAttributes(true); Attribute attrib; DataFormat dataFormat = DataFormat.Default; bool ignore = false; object defaultValue = null; // implicit zero default switch (Type.GetTypeCode(effectiveType)) { case TypeCode.Boolean: defaultValue = false; break; case TypeCode.Decimal: defaultValue = (decimal)0; break; case TypeCode.Single: defaultValue = (float)0; break; case TypeCode.Double: defaultValue = (double)0; break; case TypeCode.Byte: defaultValue = (byte)0; break; case TypeCode.Char: defaultValue = (char)0; break; case TypeCode.Int16: defaultValue = (short)0; break; case TypeCode.Int32: defaultValue = (int)0; break; case TypeCode.Int64: defaultValue = (long)0; break; case TypeCode.SByte: defaultValue = (sbyte)0; break; case TypeCode.UInt16: defaultValue = (ushort)0; break; case TypeCode.UInt32: defaultValue = (uint)0; break; case TypeCode.UInt64: defaultValue = (ulong)0; break; default: if (effectiveType == typeof(TimeSpan)) defaultValue = TimeSpan.Zero; if (effectiveType == typeof(Guid)) defaultValue = Guid.Empty; break; } bool done = false; if (isEnum) { attrib = GetAttribute(attribs, "ProtoBuf.ProtoIgnoreAttribute"); if (attrib != null) { ignore = true; } else { attrib = GetAttribute(attribs, "ProtoBuf.ProtoEnumAttribute"); fieldNumber = Convert.ToInt32(((FieldInfo)member).GetValue(null)); if (attrib != null) { GetFieldName(ref name, attrib, "Name"); if ((bool)attrib.GetType().GetMethod("HasValue").Invoke(attrib, null)) { fieldNumber = (int) GetMemberValue(attrib, "Value"); } } } done = true; } if (!ignore && !done) // always consider ProtoMember { attrib = GetAttribute(attribs, "ProtoBuf.ProtoMemberAttribute"); GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.ProtoIgnoreAttribute"); if (!ignore) { GetFieldNumber(ref fieldNumber, attrib, "Tag"); GetFieldName(ref name, attrib, "Name"); GetFieldBoolean(ref isRequired, attrib, "IsRequired"); GetFieldBoolean(ref isPacked, attrib, "IsPacked"); GetDataFormat(ref dataFormat, attrib, "DataFormat"); done = fieldNumber > 0; } if (!done && partialMembers != null) { foreach (ProtoPartialMemberAttribute ppma in partialMembers) { if (ppma.MemberName == member.Name) { GetFieldNumber(ref fieldNumber, ppma, "Tag"); GetFieldName(ref name, ppma, "Name"); GetFieldBoolean(ref isRequired, ppma, "IsRequired"); GetFieldBoolean(ref isPacked, ppma, "IsPacked"); GetDataFormat(ref dataFormat, ppma, "DataFormat"); if (done = fieldNumber > 0) break; } } } } if (!ignore && !done && HasFamily(family, AttributeFamily.DataContractSerialier)) { attrib = GetAttribute(attribs, "System.Runtime.Serialization.DataMemberAttribute"); GetFieldNumber(ref fieldNumber, attrib, "Order"); GetFieldName(ref name, attrib, "Name"); GetFieldBoolean(ref isRequired, attrib, "IsRequired"); done = fieldNumber > 0; } if (!ignore && !done && HasFamily(family, AttributeFamily.XmlSerializer)) { attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlElementAttribute"); GetIgnore(ref ignore, attrib, attribs, "System.Xml.Serialization.XmlIgnoreAttribute"); if (!ignore) { GetFieldNumber(ref fieldNumber, attrib, "Order"); GetFieldName(ref name, attrib, "ElementName"); } attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlArrayAttribute"); GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.XmlIgnoreAttribute"); if (!ignore) { GetFieldNumber(ref fieldNumber, attrib, "Order"); GetFieldName(ref name, attrib, "ElementName"); } done = fieldNumber > 0; } if (!ignore && (attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null) { defaultValue = GetMemberValue(attrib, "Value"); } ValueMember vm = ((isEnum || fieldNumber > 0) && !ignore) ? new ValueMember(model, type, fieldNumber, member, effectiveType, itemType, defaultType, dataFormat, defaultValue) : null; if (vm != null) { PropertyInfo prop = type.GetProperty(member.Name + "Specified", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, typeof(bool), Helpers.EmptyTypes, null); if (prop != null) { vm.SetSpecified(prop.GetGetMethod(true), prop.GetSetMethod(true)); } else { MethodInfo method = type.GetMethod("ShouldSerialize" + member.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Helpers.EmptyTypes, null); if (method != null && method.ReturnType == typeof(bool)) { vm.SetSpecified(method, null); } } if(!Helpers.IsNullOrEmpty(name)) vm.SetName(name); vm.IsPacked = isPacked; vm.IsRequired = isRequired; } return vm; }
private static bool HasFamily(AttributeFamily value, AttributeFamily required) { return (value & required) == required; }
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; }
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); }
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)); } }
protected virtual AttributeFamily GetContractFamily(Type type, AttributeMap[] attributes) { if (Helpers.GetNullableUnderlyingType(type) != null) { return(AttributeFamily.None); } if (!Helpers.IsEnum(type) && Helpers.GetTypeCode(type) != ProtoTypeCode.Unknown) { return(AttributeFamily.None); // known types are not contracts } AttributeFamily family = AttributeFamily.None; bool isList = type.IsArray || TypeModel.GetListItemType(Model, type) != null; for (int i = 0; i < attributes.Length; i++) { switch (attributes[i].AttributeType.FullName) { case "ProtoBuf.ProtoContractAttribute": { if (CanUse(AttributeType.ProtoBuf)) { bool tmp = false; GetFieldBoolean(ref tmp, attributes[i], "UseProtoMembersOnly"); if (tmp) { return(AttributeFamily.ProtoBuf); } family |= AttributeFamily.ProtoBuf; } } break; case "AqlaSerializer.SerializableTypeAttribute": { if (CanUse(AttributeType.Aqla)) { bool tmp = false; GetFieldBoolean(ref tmp, attributes[i], "UseAqlaMembersOnly"); if (tmp) { return(AttributeFamily.Aqla); } family |= AttributeFamily.Aqla; } } break; case "System.Xml.Serialization.XmlTypeAttribute": if (CanUse(AttributeType.Xml)) { family |= AttributeFamily.XmlSerializer; } break; case "System.Runtime.Serialization.DataContractAttribute": if (CanUse(AttributeType.DataContract)) { family |= AttributeFamily.DataContractSerialier; } break; } } if (family == AttributeFamily.None) { if (Helpers.IsEnum(type)) { // it's not required to specify attributes on enum if (CanUse(AttributeType.ProtoBuf) && !CanUse(AttributeType.Aqla)) { family |= AttributeFamily.ProtoBuf; } else { family |= AttributeFamily.Aqla; } } else if (!DisableAutoTuples) { // check for obvious tuples // AqlaSerializer: as-reference is // a default behavior for classes // and if type attribute is not set // such behavior should apply. // This will not be called if // there are any attributes! MemberInfo[] mapping; if (MetaType.ResolveTupleConstructor(type, out mapping) != null) { family |= AttributeFamily.AutoTuple; } } if (family == AttributeFamily.None && ImplicitFallbackMode != ImplicitFieldsMode.None && !isList) { if (Helpers.GetTypeCode(type) == ProtoTypeCode.Unknown && type != Model.MapType(typeof(object)) && type != Model.MapType(typeof(ValueType))) { family = AttributeFamily.ImplicitFallback; } } if (family == AttributeFamily.None && CanUse(AttributeType.SystemSerializable) && !isList) { for (int i = 0; i < attributes.Length; i++) { switch (attributes[i].AttributeType.FullName) { case "System.SerializableAttribute": family |= AttributeFamily.SystemSerializable; break; } } } } return(family); }