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