Beispiel #1
0
 /// <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);
 }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
                }
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #6
0
 public FinalizingSettingsArgs(ValueMember member)
 {
     Member = member;
 }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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('}');
            }
        }
Beispiel #9
0
 void AddTupleField(ValueMember vm)
 {
     vm.FinalizingSettings += (s, a) => FinalizingMemberSettings?.Invoke(this, a);
     _tupleFields.Add(vm);
 }