예제 #1
0
        private IProtoSerializer BuildSerializer()
        {
            WireType         wireType;
            IProtoSerializer ser = GetCoreSerializer(itemType ?? memberType, out wireType);

            // apply tags
            ser = new TagDecorator(fieldNumber, wireType, isStrict, ser);
            // apply lists if appropriate
            if (itemType != null)
            {
                Helpers.DebugAssert(itemType == ser.ExpectedType, "Wrong type in the tail");
                if (memberType.IsArray)
                {
                    ser = new ArrayDecorator(ser, isPacked ? fieldNumber : 0, isPacked ? wireType : WireType.None);
                }
                else
                {
                    ser = new ListDecorator(memberType, defaultType, ser, isPacked ? fieldNumber : 0, isPacked ? wireType : WireType.None);
                }
            }
            else if (defaultValue != null && !isRequired)
            {
                ser = new DefaultValueDecorator(defaultValue, ser);
            }
            if (memberType == typeof(Uri))
            {
                ser = new UriDecorator(ser);
            }
            switch (member.MemberType)
            {
            case MemberTypes.Property:
                ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break;

            case MemberTypes.Field:
                ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break;

            default:
                throw new InvalidOperationException();
            }
            if (getSpecified != null || setSpecified != null)
            {
                ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
            }
            return(ser);
        }
예제 #2
0
        IProtoSerializerWithWireType BuildSerializer()
        {
            if (_serializer != null)
            {
                return(_serializer);
            }

            int opaqueToken = 0;

            try
            {
                // this lock is for whole model, not just this value member
                // so it should be taken anyway, right?
                _model.TakeLock(ref opaqueToken); // check nobody is still adding this type

                if (_serializer != null)
                {
                    return(_serializer);                     // double check
                }
                FinalizingSettings?.Invoke(this, new FinalizingSettingsArgs(this));

                if (FieldNumber < 1 && !Helpers.IsEnum(ParentType) && !_isAccessHandledOutside)
                {
                    throw new ProtoException("FieldNumber < 1 for member " + Member);
                }

                if (Helpers.IsNullOrEmpty(_main.Name))
                {
                    _main.Name = Member.Name;
                }

                _vsFinal = _vsByClient.Clone();

                var level0 = _vsFinal.GetSettingsCopy(0);
                if (level0.Basic.EffectiveType == null)
                {
                    level0.Basic.EffectiveType = MemberType;
                }
                if (!level0.IsNotAssignable)
                {
                    level0.IsNotAssignable = !Helpers.CanWrite(_model, Member);
                }
                _vsFinal.SetSettings(level0, 0);

                if (_vsFinal.DefaultValue != null && _getSpecified != null)
                {
                    throw new ProtoException("Can't use default value \"" + _vsFinal.DefaultValue + "\" on member with *Specified or ShouldSerialize check " + Member);
                }

                if (_vsFinal.DefaultValue != null && IsRequired)
                {
                    throw new ProtoException("Can't use default value \"" + _vsFinal.DefaultValue + "\" on Required member " + Member);
                }

                if (_getSpecified == null && !IsRequired && _vsFinal.DefaultValue == null)
                {
                    if (_model.UseImplicitZeroDefaults)
                    {
                        switch (Helpers.GetTypeCode(MemberType))
                        {
                        case ProtoTypeCode.Boolean:
                            _vsFinal.DefaultValue = false;
                            break;

                        case ProtoTypeCode.Decimal:
                            _vsFinal.DefaultValue = (decimal)0;
                            break;

                        case ProtoTypeCode.Single:
                            _vsFinal.DefaultValue = (float)0;
                            break;

                        case ProtoTypeCode.Double:
                            _vsFinal.DefaultValue = (double)0;
                            break;

                        case ProtoTypeCode.Byte:
                            _vsFinal.DefaultValue = (byte)0;
                            break;

                        case ProtoTypeCode.Char:
                            _vsFinal.DefaultValue = (char)0;
                            break;

                        case ProtoTypeCode.Int16:
                            _vsFinal.DefaultValue = (short)0;
                            break;

                        case ProtoTypeCode.Int32:
                            _vsFinal.DefaultValue = (int)0;
                            break;

                        case ProtoTypeCode.Int64:
                            _vsFinal.DefaultValue = (long)0;
                            break;

                        case ProtoTypeCode.SByte:
                            _vsFinal.DefaultValue = (sbyte)0;
                            break;

                        case ProtoTypeCode.UInt16:
                            _vsFinal.DefaultValue = (ushort)0;
                            break;

                        case ProtoTypeCode.UInt32:
                            _vsFinal.DefaultValue = (uint)0;
                            break;

                        case ProtoTypeCode.UInt64:
                            _vsFinal.DefaultValue = (ulong)0;
                            break;

                        case ProtoTypeCode.TimeSpan:
                            _vsFinal.DefaultValue = TimeSpan.Zero;
                            break;

                        case ProtoTypeCode.Guid:
                            _vsFinal.DefaultValue = Guid.Empty;
                            break;
                        }
                    }
                }

#if !DEBUG
                try
#endif
                {
                    WireType wt;
                    var      ser = _model.ValueSerializerBuilder.BuildValueFinalSerializer(
                        _vsFinal,
                        true,
                        out wt);

                    if (!_isAccessHandledOutside)
                    {
                        PropertyInfo prop = Member as PropertyInfo;
                        if (prop != null)
                        {
                            ser = new PropertyDecorator(_model, ParentType, (PropertyInfo)Member, ser);
                        }
                        else
                        {
                            FieldInfo fld = Member as FieldInfo;
                            if (fld != null)
                            {
                                ser = new FieldDecorator(ParentType, (FieldInfo)Member, ser);
                            }
                            else
                            {
                                throw new InvalidOperationException();
                            }
                        }

                        if (_getSpecified != null || _setSpecified != null)
                        {
                            ser = new MemberSpecifiedDecorator(_getSpecified, _setSpecified, ser);
                        }
                    }
                    _serializer = ser;

                    return(ser);
                }
#if !DEBUG
                catch (ProtoException ex)
                {
                    throw new ProtoException(GetRethrowExceptionText(ex), ex);
                }
                catch (InvalidOperationException ex)
                {
                    throw new InvalidOperationException(GetRethrowExceptionText(ex), ex);
                }
                catch (NotSupportedException ex)
                {
                    throw new InvalidOperationException(GetRethrowExceptionText(ex), ex);
                }
                catch (NotImplementedException ex)
                {
                    throw new NotImplementedException(GetRethrowExceptionText(ex), ex);
                }
                catch (ArgumentNullException ex)
                {
                    throw new ArgumentNullException(GetRethrowExceptionText(ex), ex);
                }
                catch (ArgumentOutOfRangeException ex)
                {
                    throw new ArgumentOutOfRangeException(GetRethrowExceptionText(ex), ex);
                }
                catch (ArgumentException ex)
                {
#if SILVERLIGHT || PORTABLE
                    throw new ArgumentException(GetRethrowExceptionText(ex), ex);
#else
                    throw new ArgumentException(GetRethrowExceptionText(ex), ex.ParamName, ex);
#endif
                }
                catch (System.MissingMemberException ex)
                {
                    throw new System.MissingMemberException(GetRethrowExceptionText(ex), ex);
                }
                catch (MemberAccessException ex)
                {
                    throw new MemberAccessException(GetRethrowExceptionText(ex), ex);
                }
                catch (Exception ex)
                {
                    throw new ProtoException(GetRethrowExceptionText(ex), ex);
                }
#endif
            }
            finally
            {
                _model.ReleaseLock(opaqueToken);
            }
        }
예제 #3
0
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);// check nobody is still adding this type
                WireType         wireType;
                Type             finalType = itemType == null ? memberType : itemType;
                IProtoSerializer ser       = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList, true);
                if (ser == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                }

                // apply tags
                if (itemType != null && SupportNull)
                {
                    if (IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser);
                    ser = new NullDecorator(model, ser);
                    ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser);
                }
                else
                {
                    ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                }
                // apply lists if appropriate
                if (itemType != null)
                {
#if NO_GENERICS
                    Type underlyingItemType = itemType;
#else
                    Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType;
#endif
                    Helpers.DebugAssert(underlyingItemType == ser.ExpectedType ||
                                        (ser.ExpectedType == model.MapType(typeof(object)) && !Helpers.IsValueType(underlyingItemType))
                                        , "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
                    if (memberType.IsArray)
                    {
                        ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull);
                    }
                    else
                    {
                        ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull);
                    }
                }
                else if (defaultValue != null && !IsRequired && getSpecified == null)
                {   // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue,
                    // as does "IsRequired"
                    ser = new DefaultValueDecorator(model, defaultValue, ser);
                }
                if (memberType == model.MapType(typeof(Uri)))
                {
                    ser = new UriDecorator(model, ser);
                }
#if PORTABLE
                else if (memberType.FullName == typeof(Uri).FullName)
                {
                    // In PCLs, the Uri type may not match (WinRT uses Internal/Uri, .Net uses System/Uri)
                    ser = new ReflectedUriDecorator(memberType, model, ser);
                }
#endif
                if (member != null)
                {
                    PropertyInfo prop = member as PropertyInfo;
                    if (prop != null)
                    {
                        ser = new PropertyDecorator(model, parentType, (PropertyInfo)member, ser);
                    }
                    else
                    {
                        FieldInfo fld = member as FieldInfo;
                        if (fld != null)
                        {
                            ser = new FieldDecorator(parentType, (FieldInfo)member, ser);
                        }
                        else
                        {
                            throw new InvalidOperationException();
                        }
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
예제 #4
0
        private IProtoSerializer BuildSerializer()
        {
            bool lockTaken = false;

            try
            {
                model.TakeLock(ref lockTaken);// check nobody is still adding this type
                WireType         wireType;
                Type             finalType = itemType == null ? memberType : itemType;
                IProtoSerializer ser       = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType);
                if (ser == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                }
                // apply tags
                ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                // apply lists if appropriate
                if (itemType != null)
                {
                    Helpers.DebugAssert(itemType == ser.ExpectedType, "Wrong type in the tail");
                    if (memberType.IsArray)
                    {
                        ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList);
                    }
                    else
                    {
                        ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList);
                    }
                }
                else if (defaultValue != null && !IsRequired)
                {
                    ser = new DefaultValueDecorator(defaultValue, ser);
                }
                if (memberType == typeof(Uri))
                {
                    ser = new UriDecorator(ser);
                }
                if (member != null)
                {
                    switch (member.MemberType)
                    {
                    case MemberTypes.Property:
                        ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break;

                    case MemberTypes.Field:
                        ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break;

                    default:
                        throw new InvalidOperationException();
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(lockTaken);
            }
        }
예제 #5
0
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);// check nobody is still adding this type
                var member = backingMember ?? originalMember;
                IProtoSerializer ser;
                if (IsMap)
                {
                    ResolveMapTypes(out var dictionaryType, out var keyType, out var valueType);

                    if (dictionaryType == null)
                    {
                        throw new InvalidOperationException("Unable to resolve map type for type: " + memberType.FullName);
                    }
                    var concreteType = defaultType;
                    if (concreteType == null && Helpers.IsClass(memberType))
                    {
                        concreteType = memberType;
                    }
                    var keySer = TryGetCoreSerializer(model, MapKeyFormat, keyType, out var keyWireType, false, false, false, false);
                    if (!AsReference)
                    {
                        AsReference = MetaType.GetAsReferenceDefault(model, valueType);
                    }
                    var valueSer = TryGetCoreSerializer(model, MapValueFormat, valueType, out var valueWireType, AsReference, DynamicType, false, true);
#if PROFILE259
                    IEnumerable <ConstructorInfo> ctors = typeof(MapDecorator <, ,>).MakeGenericType(new Type[] { dictionaryType, keyType, valueType }).GetTypeInfo().DeclaredConstructors;
                    if (ctors.Count() != 1)
                    {
                        throw new InvalidOperationException("Unable to resolve MapDecorator constructor");
                    }
                    ser = (IProtoSerializer)ctors.First().Invoke(new object[] { model, concreteType, keySer, valueSer, fieldNumber,
                                                                                DataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String, keyWireType, valueWireType, OverwriteList });
#else
                    var ctors = typeof(MapDecorator <, ,>).MakeGenericType(new Type[] { dictionaryType, keyType, valueType }).GetConstructors(
                        BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                    if (ctors.Length != 1)
                    {
                        throw new InvalidOperationException("Unable to resolve MapDecorator constructor");
                    }
                    ser = (IProtoSerializer)ctors[0].Invoke(new object[] { model, concreteType, keySer, valueSer, fieldNumber,
                                                                           DataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String, keyWireType, valueWireType, OverwriteList });
#endif
                }
                else
                {
                    WireType wireType;
                    Type     finalType = itemType == null ? memberType : itemType;
                    ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, AsReference, DynamicType, OverwriteList, true);
                    if (ser == null)
                    {
                        throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                    }

                    // apply tags
                    if (itemType != null && SupportNull)
                    {
                        if (IsPacked)
                        {
                            throw new NotSupportedException("Packed encodings cannot support null values");
                        }
                        ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser);
                        ser = new NullDecorator(model, ser);
                        ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser);
                    }
                    else
                    {
                        ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                    }
                    // apply lists if appropriate
                    if (itemType != null)
                    {
                        Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType;

                        Helpers.DebugAssert(underlyingItemType == ser.ExpectedType ||
                                            (ser.ExpectedType == model.MapType(typeof(object)) && !Helpers.IsValueType(underlyingItemType))
                                            , "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
                        if (memberType.IsArray)
                        {
                            ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull);
                        }
                        else
                        {
                            ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull);
                        }
                    }
                    else if (defaultValue != null && !IsRequired && getSpecified == null)
                    {   // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue,
                        // as does "IsRequired"
                        ser = new DefaultValueDecorator(model, defaultValue, ser);
                    }
                    if (memberType == model.MapType(typeof(Uri)))
                    {
                        ser = new UriDecorator(model, ser);
                    }
#if PORTABLE
                    else if (memberType.FullName == typeof(Uri).FullName)
                    {
                        // In PCLs, the Uri type may not match (WinRT uses Internal/Uri, .Net uses System/Uri)
                        ser = new ReflectedUriDecorator(memberType, model, ser);
                    }
#endif
                }
                if (member != null)
                {
                    if (member is PropertyInfo prop)
                    {
                        ser = new PropertyDecorator(model, parentType, prop, ser);
                    }
                    else if (member is FieldInfo fld)
                    {
                        ser = new FieldDecorator(parentType, fld, ser);
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }

                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
예제 #6
0
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);// check nobody is still adding this type
                WireType         wireType;
                Type             finalType = itemType == null ? memberType : itemType;
                IProtoSerializer ser       = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList);
                if (ser == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                }
                // apply tags
                if (itemType != null && SupportNull)
                {
                    if (IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser);
                    ser = new NullDecorator(ser);
                    ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser);
                }
                else
                {
                    ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                }
                // apply lists if appropriate
                if (itemType != null)
                {
#if NO_GENERICS
                    Type underlyingItemType = itemType;
#else
                    Type underlyingItemType = SupportNull ? itemType : Nullable.GetUnderlyingType(itemType) ?? itemType;
#endif
                    Helpers.DebugAssert(underlyingItemType == ser.ExpectedType, "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
                    if (memberType.IsArray)
                    {
                        ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull);
                    }
                    else
                    {
                        ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList, SupportNull);
                    }
                }
                else if (defaultValue != null && !IsRequired)
                {
                    ser = new DefaultValueDecorator(defaultValue, ser);
                }
                if (memberType == typeof(Uri))
                {
                    ser = new UriDecorator(ser);
                }
                if (member != null)
                {
                    switch (member.MemberType)
                    {
                    case MemberTypes.Property:
                        ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break;

                    case MemberTypes.Field:
                        ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break;

                    default:
                        throw new InvalidOperationException();
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
예제 #7
0
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);
                Type             type            = (itemType == null) ? memberType : itemType;
                IProtoSerializer protoSerializer = TryGetCoreSerializer(model, dataFormat, type, out WireType defaultWireType, asReference, dynamicType, OverwriteList, allowComplexTypes: true);
                if (protoSerializer == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + type.FullName);
                }
                if (itemType != null && SupportNull)
                {
                    if (IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    protoSerializer = new TagDecorator(1, defaultWireType, IsStrict, protoSerializer);
                    protoSerializer = new NullDecorator(model, protoSerializer);
                    protoSerializer = new TagDecorator(fieldNumber, WireType.StartGroup, strict: false, protoSerializer);
                }
                else
                {
                    protoSerializer = new TagDecorator(fieldNumber, defaultWireType, IsStrict, protoSerializer);
                }
                if (itemType != null)
                {
                    if (!SupportNull)
                    {
                        if (Helpers.GetUnderlyingType(itemType) == null)
                        {
                            _ = itemType;
                        }
                    }
                    else
                    {
                        _ = itemType;
                    }
                    protoSerializer = ((!memberType.IsArray) ? ((ProtoDecoratorBase)ListDecorator.Create(model, memberType, defaultType, protoSerializer, fieldNumber, IsPacked, defaultWireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull)) : ((ProtoDecoratorBase) new ArrayDecorator(model, protoSerializer, fieldNumber, IsPacked, defaultWireType, memberType, OverwriteList, SupportNull)));
                }
                else if (defaultValue != null && !IsRequired && getSpecified == null)
                {
                    protoSerializer = new DefaultValueDecorator(model, defaultValue, protoSerializer);
                }
                if (memberType == model.MapType(typeof(Uri)))
                {
                    protoSerializer = new UriDecorator(model, protoSerializer);
                }
                if (member != null)
                {
                    if (member is PropertyInfo)
                    {
                        protoSerializer = new PropertyDecorator(model, parentType, (PropertyInfo)member, protoSerializer);
                    }
                    else
                    {
                        if (!(member is FieldInfo))
                        {
                            throw new InvalidOperationException();
                        }
                        protoSerializer = new FieldDecorator(parentType, (FieldInfo)member, protoSerializer);
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        protoSerializer = new MemberSpecifiedDecorator(getSpecified, setSpecified, protoSerializer);
                    }
                }
                return(protoSerializer);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
예제 #8
0
        private IProtoSerializer BuildSerializer()
        {
            IProtoSerializer serializer2;
            int opaqueToken = 0;

            try
            {
                WireType type;
                this.model.TakeLock(ref opaqueToken);
                Type             type2 = (this.itemType == null) ? this.memberType : this.itemType;
                IProtoSerializer tail  = TryGetCoreSerializer(this.model, this.dataFormat, type2, out type, this.asReference, this.dynamicType, this.OverwriteList, true);
                if (tail == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + type2.FullName);
                }
                if ((this.itemType != null) && this.SupportNull)
                {
                    if (this.IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    tail = new TagDecorator(1, type, this.IsStrict, tail);
                    tail = new NullDecorator(this.model, tail);
                    tail = new TagDecorator(this.fieldNumber, WireType.StartGroup, false, tail);
                }
                else
                {
                    tail = new TagDecorator(this.fieldNumber, type, this.IsStrict, tail);
                }
                if (this.itemType != null)
                {
                    if (!this.SupportNull)
                    {
                        Helpers.GetUnderlyingType(this.itemType);
                    }
                    if (this.memberType.IsArray)
                    {
                        tail = new ArrayDecorator(this.model, tail, this.fieldNumber, this.IsPacked, type, this.memberType, this.OverwriteList, this.SupportNull);
                    }
                    else
                    {
                        tail = new ListDecorator(this.model, this.memberType, this.defaultType, tail, this.fieldNumber, this.IsPacked, type, (this.member != null) && PropertyDecorator.CanWrite(this.model, this.member), this.OverwriteList, this.SupportNull);
                    }
                }
                else if (((this.defaultValue != null) && !this.IsRequired) && (this.getSpecified == null))
                {
                    tail = new DefaultValueDecorator(this.model, this.defaultValue, tail);
                }
                if (this.memberType == this.model.MapType(typeof(Uri)))
                {
                    tail = new UriDecorator(this.model, tail);
                }
                if (this.member != null)
                {
                    PropertyInfo member = this.member as PropertyInfo;
                    if (member != null)
                    {
                        tail = new PropertyDecorator(this.model, this.parentType, (PropertyInfo)this.member, tail);
                    }
                    else
                    {
                        FieldInfo info2 = this.member as FieldInfo;
                        if (info2 == null)
                        {
                            throw new InvalidOperationException();
                        }
                        tail = new FieldDecorator(this.parentType, (FieldInfo)this.member, tail);
                    }
                    if ((this.getSpecified != null) || (this.setSpecified != null))
                    {
                        tail = new MemberSpecifiedDecorator(this.getSpecified, this.setSpecified, tail);
                    }
                }
                serializer2 = tail;
            }
            finally
            {
                this.model.ReleaseLock(opaqueToken);
            }
            return(serializer2);
        }
예제 #9
0
        // Token: 0x0600040A RID: 1034 RVA: 0x00015168 File Offset: 0x00013368
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;
            IProtoSerializer result;

            try
            {
                this.model.TakeLock(ref opaqueToken);
                Type             type = (this.itemType == null) ? this.memberType : this.itemType;
                WireType         wireType;
                IProtoSerializer protoSerializer = ValueMember.TryGetCoreSerializer(this.model, this.dataFormat, type, out wireType, this.asReference, this.dynamicType, this.OverwriteList, true);
                if (protoSerializer == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + type.FullName);
                }
                if (this.itemType != null && this.SupportNull)
                {
                    if (this.IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    protoSerializer = new TagDecorator(1, wireType, this.IsStrict, protoSerializer);
                    protoSerializer = new NullDecorator(this.model, protoSerializer);
                    protoSerializer = new TagDecorator(this.fieldNumber, WireType.StartGroup, false, protoSerializer);
                }
                else
                {
                    protoSerializer = new TagDecorator(this.fieldNumber, wireType, this.IsStrict, protoSerializer);
                }
                if (this.itemType != null)
                {
                    if (!this.SupportNull)
                    {
                        if (Helpers.GetUnderlyingType(this.itemType) == null)
                        {
                            Type type2 = this.itemType;
                        }
                    }
                    else
                    {
                        Type type3 = this.itemType;
                    }
                    if (this.memberType.IsArray)
                    {
                        protoSerializer = new ArrayDecorator(this.model, protoSerializer, this.fieldNumber, this.IsPacked, wireType, this.memberType, this.OverwriteList, this.SupportNull);
                    }
                    else
                    {
                        protoSerializer = ListDecorator.Create(this.model, this.memberType, this.defaultType, protoSerializer, this.fieldNumber, this.IsPacked, wireType, this.member != null && PropertyDecorator.CanWrite(this.model, this.member), this.OverwriteList, this.SupportNull);
                    }
                }
                else if (this.defaultValue != null && !this.IsRequired && this.getSpecified == null)
                {
                    protoSerializer = new DefaultValueDecorator(this.model, this.defaultValue, protoSerializer);
                }
                if (this.memberType == this.model.MapType(typeof(Uri)))
                {
                    protoSerializer = new UriDecorator(this.model, protoSerializer);
                }
                if (this.member != null)
                {
                    if (this.member is PropertyInfo)
                    {
                        protoSerializer = new PropertyDecorator(this.model, this.parentType, (PropertyInfo)this.member, protoSerializer);
                    }
                    else
                    {
                        if (!(this.member is FieldInfo))
                        {
                            throw new InvalidOperationException();
                        }
                        protoSerializer = new FieldDecorator(this.parentType, (FieldInfo)this.member, protoSerializer);
                    }
                    if (this.getSpecified != null || this.setSpecified != null)
                    {
                        protoSerializer = new MemberSpecifiedDecorator(this.getSpecified, this.setSpecified, protoSerializer);
                    }
                }
                result = protoSerializer;
            }
            finally
            {
                this.model.ReleaseLock(opaqueToken);
            }
            return(result);
        }