Beispiel #1
0
 static void CheckAnyAuxFlow(SerializerFeatures features, ISerializer <T> serializer)
 {
     if ((features & TypeModel.FromAux) != 0 && serializer.Features.GetCategory() == SerializerFeatures.CategoryMessageWrappedAtRoot)
     {
         ThrowHelper.ThrowNotImplementedException($"Tell Marc: ambiguous category in an any/aux flow for {typeof(T).NormalizeName()}");
     }
 }
Beispiel #2
0
            protected override bool TrySerializeAny(int fieldNumber, SerializerFeatures features, TypeModel model, ref ProtoWriter.State state, object value)
            {
                var serializer = TypeModel.TryGetSerializer <T>(model);

                if (serializer == null)
                {
                    return(false);
                }
                // note this null-check is non-trivial; for value-type T it promotes the null to a default
                T typed = TypeHelper <T> .FromObject(value);

                CheckAnyAuxFlow(features, serializer);
                if ((features & SerializerFeatures.CategoryMessageWrappedAtRoot) == SerializerFeatures.CategoryMessageWrappedAtRoot)
                {
                    if (fieldNumber != TypeModel.ListItemTag)
                    {
                        ThrowHelper.ThrowInvalidOperationException($"Special root-like wrapping is limited to field {TypeModel.ListItemTag}");
                    }
                    state.WriteAsRoot <T>(typed, serializer);
                }
                else
                {
                    state.WriteAny <T>(fieldNumber, features, typed, serializer);
                }
                return(true);
            }
Beispiel #3
0
 internal KeyValuePairSerializer(
     ISerializer <TKey> keySerializer, SerializerFeatures keyFeatures,
     ISerializer <TValue> valueSerializer, SerializerFeatures valueFeatures)
 {
     _keySerializer   = keySerializer;
     _valueSerializer = valueSerializer;
     _keyFeatures     = keyFeatures;
     _valueFeatures   = valueFeatures;
 }
Beispiel #4
0
 public SurrogateSerializer(Type declaredType, MethodInfo toTail, MethodInfo fromTail, IRuntimeProtoSerializerNode rootTail, SerializerFeatures features)
 {
     Debug.Assert(declaredType is object, "declaredType");
     Debug.Assert(rootTail is object, "rootTail");
     Debug.Assert(declaredType == rootTail.ExpectedType || Helpers.IsSubclassOf(declaredType, rootTail.ExpectedType), "surrogate type mismatch");
     this.declaredType = declaredType;
     this.rootTail     = rootTail;
     this.toTail       = toTail ?? GetConversion(true);
     this.fromTail     = fromTail ?? GetConversion(false);
     this.features     = features;
 }
Beispiel #5
0
 public static IRuntimeProtoSerializerNode Create(RepeatedSerializerStub provider, Type keyType, Type valueType,
                                                  int fieldNumber, SerializerFeatures features,
                                                  SerializerFeatures keyFeatures, SerializerFeatures valueFeatures)
 {
     if (provider == null)
     {
         ThrowHelper.ThrowArgumentNullException(nameof(provider));
     }
     _ = provider.Serializer; // primes and validates
     return((IRuntimeProtoSerializerNode)Activator.CreateInstance(
                typeof(MapDecorator <, ,>).MakeGenericType(provider.ForType, keyType, valueType),
                new object[] { fieldNumber, features, keyFeatures, valueFeatures, provider }));
 }
Beispiel #6
0
 internal static bool TrySerializeAny(int fieldNumber, SerializerFeatures features, Type type, TypeModel model, ref ProtoWriter.State state, object value)
 {
     do
     {
         if (Get(type).TrySerializeAny(fieldNumber, features, model, ref state, value))
         {
             return(true);
         }
         // since we might be ignoring sub-types, we need to walk upwards and check all
         type = type.BaseType;
     } while (type is object && type != typeof(object));
     return(false);
 }
        internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, TCollection values, ISerializer <T> serializer)
        {
            var iter = values.GetEnumerator();

            try
            {
                Write(ref state, fieldNumber, category, wireType, ref iter, serializer);
            }
            finally
            {
                iter?.Dispose();
            }
        }
Beispiel #8
0
        /*
         * 22 = field 4, type String
         * 07 = length 7
         * 08 = field 1, type Varint
         * 01 = -1 (zigzag)
         * 12 = field 2, type String
         * 03 = length 3
         * 61-62-63 = abc
         * 22 = field 4, type String
         * 05 = length 5
         * 12 = field 2, type String
         * 03 = length 3
         * 64-65-66 = def
         * 22 = field 4, type String
         * 07 = length 7
         * 08 = field 1, type Varint
         * 02 = 1 (zigzag)
         * 12 = field 2, type String
         * 03 = length 3
         * 67-68-69 = ghi
         */
        public void ReadWriteMapWorks(SerializerFeatures keyFeatures, string expected)
        {
            using var ms = new MemoryStream();

            var data = new Dictionary <int, string>
            {
                { -1, "abc" },
                { 0, "def" },
                { 1, "ghi" },
            };

            var writer = ProtoWriter.State.Create(ms, null);

            try
            {
                MapSerializer.CreateDictionary <int, string>().WriteMap(ref writer, 4, default, data, keyFeatures, default);
Beispiel #9
0
        public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members, SerializerFeatures features, CompatibilityLevel compatibilityLevel)
        {
            this.ctor    = ctor ?? throw new ArgumentNullException(nameof(ctor));
            this.members = members ?? throw new ArgumentNullException(nameof(members));
            this.tails   = new IRuntimeProtoSerializerNode[members.Length];

            Features = features;
            ParameterInfo[] parameters = ctor.GetParameters();
            for (int i = 0; i < members.Length; i++)
            {
                Type finalType = parameters[i].ParameterType;

                var  repeated = model.TryGetRepeatedProvider(finalType);
                Type tmp      = repeated?.ItemType ?? finalType;

                bool asReference = false;
                int  typeIndex   = model.FindOrAddAuto(tmp, false, true, false, compatibilityLevel);
                if (typeIndex >= 0)
                {
                    asReference = model[tmp].AsReferenceDefault;
                }
                IRuntimeProtoSerializerNode tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, compatibilityLevel, tmp, out WireType wireType, asReference, false, false, true), serializer;
                if (tail == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName);
                }

                if (repeated == null)
                {
                    serializer = new TagDecorator(i + 1, wireType, false, tail);
                }
                else if (repeated.IsMap)
                {
                    serializer = ValueMember.CreateMap(repeated, model, DataFormat.Default, compatibilityLevel, DataFormat.Default, DataFormat.Default, asReference, false, true, false, i + 1);
                }
                else
                {
                    SerializerFeatures listFeatures = wireType.AsFeatures() | SerializerFeatures.OptionPackedDisabled;
                    serializer = RepeatedDecorator.Create(repeated, i + 1, listFeatures, compatibilityLevel, DataFormat.Default);
                }
                tails[i] = serializer;
            }
        }
Beispiel #10
0
            protected override bool CanSerialize(TypeModel model, out SerializerFeatures features)
            {
                ISerializer <T> ser;

                try
                {
                    ser = TypeModel.TryGetSerializer <T>(model);
                }
                catch // then definitely no!
                {
                    features = default;
                    return(false);
                }
                if (ser == null)
                {
                    features = default;
                    return(false);
                }
                features = ser.Features;
                return(true);
            }
Beispiel #11
0
 internal static bool CanSerialize(Type type, TypeModel model, out SerializerFeatures features)
 => Get(type).CanSerialize(model, out features);
 public static SerializerFeatures GetCategory(this SerializerFeatures features)
 => features & CategoryMask;
Beispiel #13
0
 abstract internal void Init(int[] fieldNumbers, IRuntimeProtoSerializerNode[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, bool assertKnownType, CallbackSet callbacks, Type constructType, MethodInfo factory, SerializerFeatures features);
Beispiel #14
0
        public static IProtoTypeSerializer Create(Type forType, int[] fieldNumbers, IRuntimeProtoSerializerNode[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, bool assertKnownType, CallbackSet callbacks, Type constructType, MethodInfo factory, Type rootType, SerializerFeatures features)
        {
            var obj = (TypeSerializer)(rootType != null
                ? Activator.CreateInstance(typeof(InheritanceTypeSerializer <,>).MakeGenericType(rootType, forType), nonPublic: true)
                : Activator.CreateInstance(typeof(TypeSerializer <>).MakeGenericType(forType), nonPublic: true));

            obj.Init(fieldNumbers, serializers, baseCtorCallbacks, isRootType, useConstructor, assertKnownType, callbacks, constructType, factory, features);
            return((IProtoTypeSerializer)obj);
        }
        internal override void Write(ref ProtoWriter.State state, int fieldNumber, SerializerFeatures category, WireType wireType, ImmutableArray <T> values, ISerializer <T> serializer)
        {
            var iter = new Enumerator(values);

            Write(ref state, fieldNumber, category, wireType, ref iter, serializer);
        }
Beispiel #16
0
 public static IRuntimeProtoSerializerNode Create(RepeatedSerializerStub stub, int fieldNumber, SerializerFeatures features)
 {
     if (stub == null)
     {
         ThrowHelper.ThrowArgumentNullException(nameof(stub), $"No suitable repeated serializer resolved for {stub.ForType.NormalizeName()}");
     }
     _ = stub.Serializer; // primes and validates
     return((IRuntimeProtoSerializerNode)Activator.CreateInstance(typeof(RepeatedDecorator <,>).MakeGenericType(stub.ForType, stub.ItemType),
                                                                  new object[] { fieldNumber, features, stub }));
 }
 internal static bool TrySerializeAny(int fieldNumber, SerializerFeatures features, Type type, TypeModel model, ref ProtoWriter.State state, object value)
 => Get(type).TrySerializeAny(fieldNumber, features, model, ref state, value);
Beispiel #18
0
        // check a few things that should be true for valid serializers
        internal static ISerializer <T> Verify <T>(ISerializer <T> serializer)
        {
            if (serializer == null)
            {
                return(null);
            }

            try
            {
                var features = serializer.Features;
                if (serializer is IRepeatedSerializer <T> )
                {
                    const SerializerFeatures PermittedRepeatedFeatures = SerializerFeatures.CategoryRepeated;
                    if ((features & ~PermittedRepeatedFeatures) != 0)
                    {
                        ThrowInvalidSerializer(serializer, $"repeated serializers may only specify {PermittedRepeatedFeatures}");
                    }
                    return(serializer);
                }

                var wireType = features.GetWireType(); // this also asserts that a wire-type is set
                switch (wireType)
                {
                case WireType.Varint:
                case WireType.Fixed32:
                case WireType.Fixed64:
                case WireType.SignedVarint:
                case WireType.String:
                case WireType.StartGroup:
                    break;

                default:
                    ThrowInvalidSerializer(serializer, $"invalid wire-type {wireType}");
                    break;
                }

                switch (features.GetCategory())
                {
                case SerializerFeatures.CategoryMessage:
                case SerializerFeatures.CategoryMessageWrappedAtRoot:
                    if (TypeHelper <T> .CanBePacked)
                    {
                        ThrowInvalidSerializer(serializer, "message serializer specified for a type that can be 'packed'");
                    }
                    break;

                case SerializerFeatures.CategoryScalar:

                    if (TypeHelper <T> .CanBePacked)
                    {
                        switch (wireType)
                        {
                        case WireType.Varint:
                        case WireType.Fixed32:
                        case WireType.Fixed64:
                        case WireType.SignedVarint:
                            break;

                        default:
                            ThrowInvalidSerializer(serializer, "invalid wire-type for a type that can be 'packed'");
                            break;
                        }
                    }
                    break;

                default:
                    features.ThrowInvalidCategory();
                    break;
                }

                // some features should only be specified by the caller
                const SerializerFeatures InvalidFeatures = SerializerFeatures.OptionClearCollection | SerializerFeatures.OptionPackedDisabled;
                if ((features & InvalidFeatures) != 0)
                {
                    ThrowInvalidSerializer(serializer, $"serializers should not specify {InvalidFeatures}");
                }

                return(serializer);
            }
            catch (InvalidOperationException ex) when(!ex.Data.Contains("serializer"))
            {
                ThrowInvalidSerializer(serializer, ex.Message, ex);
                throw;
            }
        }
Beispiel #19
0
 protected override bool TrySerializeAny(int fieldNumber, SerializerFeatures features, TypeModel model, ref ProtoWriter.State state, object value)
 => false;
Beispiel #20
0
 protected override bool CanSerialize(TypeModel model, out SerializerFeatures features)
 {
     features = default;
     return(false);
 }