/// <summary> /// Returns the ValueMember instances associated with this type /// </summary> public ValueMember[] GetFields() { ValueMember[] arr = new ValueMember[_fields.Count]; _fields.CopyTo(arr, 0); Array.Sort(arr, ValueMember.Comparer.Default); return(arr); }
public void Add(MappedMember member) { var serializationSettings = member.MappingState.SerializationSettings.Clone(); var vm = new ValueMember(member.MainValue, serializationSettings, member.Member, this.Type, _model); #if WINRT TypeInfo finalType = _typeInfo; #else Type finalType = this.Type; #endif PropertyInfo prop = Helpers.GetProperty(finalType, member.Member.Name + "Specified", true); MethodInfo getMethod = Helpers.GetGetMethod(prop, true, true); if (getMethod == null || getMethod.IsStatic) { prop = null; } if (prop != null) { vm.SetSpecified(getMethod, Helpers.GetSetMethod(prop, true, true)); } else { MethodInfo method = Helpers.GetInstanceMethod(finalType, "ShouldSerialize" + member.Member.Name, Helpers.EmptyTypes); if (method != null && method.ReturnType == _model.MapType(typeof(bool))) { vm.SetSpecified(method, null); } } Add(vm); }
internal MetaType(RuntimeTypeModel model, Type type, MethodInfo factory) { this._factory = factory; if (model == null) { throw new ArgumentNullException(nameof(model)); } if (type == null) { throw new ArgumentNullException(nameof(type)); } this._model = model; IProtoSerializer coreSerializer = model.TryGetBasicTypeSerializer(type); if (coreSerializer != null) { throw InbuiltType(type); } this.Type = type; #if WINRT this._typeInfo = type.GetTypeInfo(); #endif MemberInfo[] members; _tupleCtor = ResolveTupleConstructor(Type, out members); if (_tupleCtor != null) { foreach (MemberInfo memberInfo in members) { var level = new MemberLevelSettingsValue(); var vs = new ValueSerializationSettings(); vs.SetSettings(new ValueSerializationSettings.LevelValue(level) { IsNotAssignable = true }, 0); vs.DefaultLevel = new ValueSerializationSettings.LevelValue(level.MakeDefaultNestedLevel()); var main = new MemberMainSettingsValue() { Name = memberInfo.Name }; var vm = new ValueMember(main, vs, memberInfo, Type, model, canHaveDefaultValue: false, isAccessHandledOutside: true); AddTupleField(vm); } } }
private void Add(ValueMember member) { int opaqueToken = 0; try { _model.TakeLock(ref opaqueToken); ThrowIfFrozen(); if (!IsFieldFree(member.FieldNumber) && !Helpers.IsEnum(Type)) { throw new ArgumentException(string.Format("FieldNumber {0} for {1} was already taken", member.FieldNumber, member), nameof(member)); } _fields.Add(member); member.FinalizingSettings += (s, a) => FinalizingMemberSettings?.Invoke(this, a); } finally { _model.ReleaseLock(opaqueToken); } }
internal EnumSerializer.EnumPair[] GetEnumMap() { if (!Helpers.IsEnum(Type)) { return(null); } if (GetFinalSettingsCopy().EnumPassthru.GetValueOrDefault()) { return(null); } var fields = _fields.Cast <ValueMember>().ToArray(); EnumSerializer.EnumPair[] result = new EnumSerializer.EnumPair[fields.Length]; for (int i = 0; i < result.Length; i++) { ValueMember member = (ValueMember)fields[i]; int wireValue = member.FieldNumber; object value = member.GetRawEnumValue(); result[i] = new EnumSerializer.EnumPair(wireValue, value, member.MemberType); } return(result); }
public FinalizingSettingsArgs(ValueMember member) { Member = member; }
private ValueMember AddField(int fieldNumber, string memberName, Type itemType, Type defaultType, object defaultValue) { if (Type.IsArray) { throw new InvalidOperationException("Can't add fields to array type"); } MemberInfo mi = null; #if WINRT mi = Helpers.IsEnum(Type) ? Type.GetTypeInfo().GetDeclaredField(memberName) : Helpers.GetInstanceMember(Type.GetTypeInfo(), memberName); #else MemberInfo[] members = Type.GetMember(memberName, Helpers.IsEnum(Type) ? BindingFlags.Static | BindingFlags.Public : BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (members != null && members.Length == 1) { mi = members[0]; } #endif if (mi == null) { throw new ArgumentException("Unable to determine member: " + memberName, nameof(memberName)); } Type miType; #if WINRT || PORTABLE PropertyInfo pi = mi as PropertyInfo; if (pi == null) { FieldInfo fi = mi as FieldInfo; if (fi == null) { throw new NotSupportedException(mi.GetType().Name); } else { miType = fi.FieldType; } } else { miType = pi.PropertyType; } #else switch (mi.MemberType) { case MemberTypes.Field: miType = ((FieldInfo)mi).FieldType; break; case MemberTypes.Property: miType = ((PropertyInfo)mi).PropertyType; break; default: throw new NotSupportedException(mi.MemberType.ToString()); } #endif // we can't check IgnoreListHandling (because of recursion when adding type) but we don't need to // it will be checked in ValueSerializedBuilder.CompleteLevel stage ResolveListTypes(_model, miType, ref itemType, ref defaultType); var serializationSettings = new ValueSerializationSettings(); var memberSettings = new MemberMainSettingsValue { Tag = fieldNumber }; var level0 = serializationSettings.GetSettingsCopy(0).Basic; level0.Collection.ConcreteType = defaultType; level0.Collection.ItemType = itemType; serializationSettings.SetSettings(level0, 0); serializationSettings.DefaultValue = defaultValue; var def = serializationSettings.DefaultLevel.GetValueOrDefault(); def.Basic = level0.MakeDefaultNestedLevel(); serializationSettings.DefaultLevel = def; ValueMember newField = new ValueMember(memberSettings, serializationSettings, mi, Type, _model); Add(newField); return(newField); }
internal void WriteSchema(System.Text.StringBuilder builder, int indent, ref bool requiresBclImport) { Serializer.GetHashCode(); if (_surrogate != null) { return; // nothing to write } ValueMember[] fieldsArr = new ValueMember[_fields.Count]; _fields.CopyTo(fieldsArr, 0); Array.Sort(fieldsArr, ValueMember.Comparer.Default); if (IsList) { string itemTypeName = _model.GetSchemaTypeName(TypeModel.GetListItemType(_model, Type), BinaryDataFormat.Default, false, false, ref requiresBclImport); NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); NewLine(builder, indent + 1).Append("repeated ").Append(itemTypeName).Append(" items = 1;"); NewLine(builder, indent).Append('}'); } else if (_settingsValueFinal.IsAutoTuple) { // key-value-pair etc MemberInfo[] mapping; if (ResolveTupleConstructor(Type, out mapping) != null) { NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); for (int i = 0; i < mapping.Length; i++) { Type effectiveType; if (mapping[i] is PropertyInfo) { effectiveType = ((PropertyInfo)mapping[i]).PropertyType; } else if (mapping[i] is FieldInfo) { effectiveType = ((FieldInfo)mapping[i]).FieldType; } else { throw new NotSupportedException("Unknown member type: " + mapping[i].GetType().Name); } NewLine(builder, indent + 1) .Append("optional ") .Append(_model.GetSchemaTypeName(effectiveType, BinaryDataFormat.Default, false, false, ref requiresBclImport).Replace('.', '_')) .Append(' ').Append(mapping[i].Name).Append(" = ").Append(i + 1).Append(';'); } NewLine(builder, indent).Append('}'); } } else if (Helpers.IsEnum(Type)) { NewLine(builder, indent).Append("enum ").Append(GetSchemaTypeName()).Append(" {"); if (_settingsValueFinal.EnumPassthru.GetValueOrDefault()) { if (Type #if WINRT .GetTypeInfo() #endif .IsDefined(_model.MapType(typeof(FlagsAttribute)), false)) { NewLine(builder, indent + 1).Append("// this is a composite/flags enumeration"); } else { NewLine(builder, indent + 1).Append("// this enumeration will be passed as a raw value"); } foreach (FieldInfo field in #if WINRT Type.GetRuntimeFields() #else Type.GetFields() #endif ) { if (field.IsStatic && field.IsLiteral) { object enumVal; #if WINRT || PORTABLE || CF || FX11 enumVal = field.GetValue(null); #else enumVal = field.GetRawConstantValue(); #endif NewLine(builder, indent + 1).Append(field.Name).Append(" = ").Append(enumVal).Append(";"); } } } else { foreach (ValueMember member in fieldsArr) { NewLine(builder, indent + 1).Append(member.Name).Append(" = ").Append(member.FieldNumber).Append(';'); } } NewLine(builder, indent).Append('}'); } else { NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); foreach (ValueMember member in fieldsArr) { member.Serializer.GetHashCode(); MemberLevelSettingsValue s = member.GetFinalSettingsCopy(0); string ordinality = s.Collection.IsCollection ? "repeated" : member.IsRequired ? "required" : "optional"; NewLine(builder, indent + 1).Append(ordinality).Append(' '); if (s.ContentBinaryFormatHint.GetValueOrDefault() == BinaryDataFormat.Group) { builder.Append("group "); } string schemaTypeName = member.GetSchemaTypeName(true, ref requiresBclImport); builder.Append(schemaTypeName).Append(" ") .Append(member.Name).Append(" = ").Append(member.FieldNumber); object defaultValue = member.GetFinalDefaultValue(); if (defaultValue != null && member.IsRequired == false) { if (defaultValue is string) { builder.Append(" [default = \"").Append(defaultValue).Append("\"]"); } else if (defaultValue is bool) { // need to be lower case (issue 304) builder.Append((bool)defaultValue ? " [default = true]" : " [default = false]"); } else { builder.Append(" [default = ").Append(defaultValue).Append(']'); } } if (s.Collection.IsCollection && s.Collection.Format == CollectionFormat.Protobuf && ListDecorator.CanPack(HelpersInternal.GetWireType(Helpers.GetTypeCode(member.MemberType), s.ContentBinaryFormatHint.GetValueOrDefault()))) { builder.Append(" [packed=true]"); } builder.Append(';'); if (schemaTypeName == "bcl.NetObjectProxy" && (s.Format == ValueFormat.Reference || s.Format == ValueFormat.LateReference) && !s.WriteAsDynamicType.GetValueOrDefault()) // we know what it is; tell the user { builder.Append(" // reference-tracked ").Append(member.GetSchemaTypeName(false, ref requiresBclImport)); } } if (_subTypes != null && _subTypes.Count != 0) { NewLine(builder, indent + 1).Append("// the following represent sub-types; at most 1 should have a value"); SubType[] subTypeArr = new SubType[_subTypes.Count]; _subTypes.CopyTo(subTypeArr, 0); Array.Sort(subTypeArr, SubType.Comparer.Default); foreach (SubType subType in subTypeArr) { string subTypeName = subType.DerivedType.GetSchemaTypeName(); NewLine(builder, indent + 1).Append("optional ").Append(subTypeName) .Append(" ").Append(subTypeName).Append(" = ").Append(subType.FieldNumber).Append(';'); } } NewLine(builder, indent).Append('}'); } }
void AddTupleField(ValueMember vm) { vm.FinalizingSettings += (s, a) => FinalizingMemberSettings?.Invoke(this, a); _tupleFields.Add(vm); }