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, false, SupportNull);
                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 (memberType.IsArray)
                    {
                        ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull, AsReference);
                    }
                    else
                    {
                    	ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType,
                    	                        member == null || PropertyDecorator.CanWrite(member), OverwriteList,
                    	                        SupportNull, AsReference);
                    }
                }*/

				WireType wireType;
				IProtoSerializer ser = GetNestedSerializer(memberType, out wireType); 
				
                Type finalType = itemType == null ? memberType : itemType;

				if (finalType != null && AsReference && finalType.FullName.StartsWith("System.Tuple`"))
				{
					MemberInfo[] mapping;
					ConstructorInfo ctor = MetaType.ResolveTupleConstructor(finalType, out mapping);
					if(ctor == null) throw new InvalidOperationException();
					ser = new TupleSerializer(model, ctor, mapping, AsReference, false, false, true, SupportNull);
					ser = new TagDecorator(fieldNumber, WireType.Variant, IsStrict, ser);
				}
				else if (defaultValue != null && !IsRequired)
				{
					ser = new DefaultValueDecorator(defaultValue, ser);
				}

                if (memberType == typeof(Uri))
                {
                    ser = new UriDecorator(ser);
                }
                if (member != null)
                {
                    PropertyInfo prop = member as PropertyInfo;
                    if (prop != null)
                    {
                        ser = new PropertyDecorator(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);
            }
        }
        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;
        }
Beispiel #3
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);
     }
 }
        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);
                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);
            }
        }