Esempio n. 1
0
        public static void Run()
        {
            TypeModelContainer container = TypeModelContainer.CreateDefault();

            container.RegisterTypeFacade <long, DateTimeOffset, DateTimeOffsetTypeFacadeConverter>();
            container.RegisterTypeFacade <byte[], Guid, GuidByteArrayConverter>();

            var example = new FacadeExampleTable
            {
                Guid      = Guid.NewGuid(),
                Timestamp = DateTimeOffset.UtcNow,
            };

            FlatBufferSerializer serializer = new FlatBufferSerializer(
                new FlatBufferSerializerOptions(FlatBufferDeserializationOption.PropertyCache),
                container);

            byte[] destination = new byte[1024];
            serializer.Serialize(example, destination);

            var parsed = serializer.Parse <FacadeExampleTable>(destination);

            Debug.Assert(parsed.Guid == example.Guid);
            Debug.Assert(parsed.Timestamp == example.Timestamp);
        }
Esempio n. 2
0
        // TODO: consider moving to TableOrStructDefinition.
        private static string GenerateSerializerForType(Assembly assembly, TableOrStructDefinition tableOrStruct)
        {
            CSharpHelpers.ConvertProtectedInternalToProtected = false;
            try
            {
                Type type      = assembly.GetType(tableOrStruct.FullName);
                var  options   = new FlatBufferSerializerOptions(tableOrStruct.RequestedSerializer.Value);
                var  generator = new RoslynSerializerGenerator(options, TypeModelContainer.CreateDefault());

                var method = generator
                             .GetType()
                             .GetMethod(nameof(RoslynSerializerGenerator.GenerateCSharp), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
                             .MakeGenericMethod(type);

                try
                {
                    string code = (string)method.Invoke(generator, new[] { "private" });
                    return(code);
                }
                catch (TargetInvocationException ex)
                {
                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                    throw;
                }
            }
            finally
            {
                CSharpHelpers.ConvertProtectedInternalToProtected = true;
            }
        }
Esempio n. 3
0
    public void Facade_NullReturnedFromConverter()
    {
        TypeModelContainer container = TypeModelContainer.CreateDefault();

        container.RegisterTypeFacade <string, DateTimeOffset, InvalidDateTimeStringConverter>();

        FlatBufferSerializer serializer = new FlatBufferSerializer(
            new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Greedy),
            container);

        byte[] destination = new byte[200];
        var    compiled    = serializer.Compile <ExtensionTable <DateTimeOffset> >();

        try
        {
            serializer.Serialize(
                new ExtensionTable <DateTimeOffset> {
                Item = DateTimeOffset.UtcNow
            },
                destination);

            Assert.False(true, "expected exception");
        }
        catch (InvalidOperationException ex)
        {
            Assert.Contains("ITypeFacadeConverter", ex.Message);
        }
    }
Esempio n. 4
0
        public void Facade_NullReturnedFromConverter2()
        {
            TypeModelContainer container = TypeModelContainer.CreateDefault();

            container.RegisterTypeFacade <long?, DateTimeOffset?, InvalidNullableDateTimeNullableLongConverter>();

            FlatBufferSerializer serializer = new FlatBufferSerializer(
                new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Greedy),
                container);

            byte[] destination = new byte[200];
            var    compiled    = serializer.Compile <ExtensionTable <DateTimeOffset?> >();

            try
            {
                serializer.Serialize(
                    new ExtensionTable <DateTimeOffset?> {
                    Item = DateTimeOffset.UtcNow
                },
                    destination);

                Assert.Fail();
            }
            catch (InvalidOperationException ex)
            {
                Assert.IsTrue(ex.Message.Contains("ITypeFacadeConverter"));
            }
        }
Esempio n. 5
0
        private static string CreateCSharp(BaseSchemaMember rootNode, CompilerOptions options)
        {
            ErrorContext.Current.ThrowIfHasErrors();

            if (string.IsNullOrEmpty(rootNode.DeclaringFile))
            {
                throw new InvalidFbsFileException("FlatSharp.Internal: RootNode missing declaring file");
            }

            Assembly?  assembly = null;
            CodeWriter writer   = new CodeWriter();
            var        steps    = new[]
            {
                CodeWritingPass.Initialization,
                CodeWritingPass.PropertyModeling,
                CodeWritingPass.SerializerGeneration,
                CodeWritingPass.RpcGeneration,
            };

            foreach (var step in steps)
            {
                var localOptions = options;

                if (step <= CodeWritingPass.PropertyModeling)
                {
                    localOptions = localOptions with {
                        NullableWarnings = false
                    };
                }

                if (step > CodeWritingPass.Initialization)
                {
                    string code = writer.ToString();
                    (assembly, _, _) = RoslynSerializerGenerator.CompileAssembly(code, true);
                }

                writer = new CodeWriter();

                rootNode.WriteCode(
                    writer,
                    new CompileContext
                {
                    CompilePass        = step,
                    Options            = localOptions,
                    RootFile           = rootNode.DeclaringFile,
                    PreviousAssembly   = assembly,
                    TypeModelContainer = TypeModelContainer.CreateDefault(),
                });

                ErrorContext.Current.ThrowIfHasErrors();
            }

            string rawCode       = writer.ToString();
            string formattedCode = RoslynSerializerGenerator.GetFormattedText(rawCode);

            return(formattedCode);
        }
    }
Esempio n. 6
0
    public void Facade_SortedVector()
    {
        TypeModelContainer container = TypeModelContainer.CreateDefault();

        container.RegisterTypeFacade <long, DateTimeOffset, DateTimeTicksConverter>();

        var ex = Assert.Throws <InvalidFlatBufferDefinitionException>(
            () => container.CreateTypeModel(typeof(ExtensionTable <IIndexedVector <DateTimeOffset, KeyTable> >)));

        Assert.Equal(
            "Table FlatSharpTests.TypeFacadeTests.KeyTable declares a key property on a type that that does not support being a key in a sorted vector.",
            ex.Message);
    }
Esempio n. 7
0
    public void Facade_Chained()
    {
        TypeModelContainer container = TypeModelContainer.CreateDefault();

        container.RegisterTypeFacade <long, TimeSpan, TimeSpanTicksConverter>();
        container.RegisterTypeFacade <TimeSpan, DateTimeOffset, DateTimeTimeSpanConverter>();

        DateTimeOffset ts            = DateTimeOffset.UtcNow;
        TimeSpan       span          = ts - DateTimeOffset.MinValue;
        long           expectedValue = span.Ticks;

        this.FacadeTest <long, TimeSpan, TimeSpanTicksConverter>(expectedValue, span, container);
        this.FacadeTest <TimeSpan, DateTimeOffset, DateTimeTimeSpanConverter>(span, ts, container);
    }
Esempio n. 8
0
 public static ParserCodeGenContext CreateParserContext(FlatBufferSerializerOptions?options = null)
 {
     return(new ParserCodeGenContext(
                "a",
                "b",
                "c",
                false,
                "d",
                new ReturnsRandomDictionary(),
                new ReturnsRandomDictionary(),
                options ?? new FlatBufferSerializerOptions(),
                TypeModelContainer.CreateDefault(),
                new Dictionary <ITypeModel, List <TableFieldContext> >()));
 }
Esempio n. 9
0
    private void FacadeTest <TUnderlyingType, TType, TConverter>(
        TUnderlyingType underlyingValue,
        TType value,
        TypeModelContainer container = null) where TConverter : struct, ITypeFacadeConverter <TUnderlyingType, TType>
    {
        if (container == null)
        {
            container = TypeModelContainer.CreateDefault();
            container.RegisterTypeFacade <TUnderlyingType, TType, TConverter>();
        }

        FlatBufferSerializer serializer = new FlatBufferSerializer(
            new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Greedy),
            container);

        byte[] destination  = new byte[1024];
        byte[] destination2 = new byte[1024];

        var compiled = serializer.Compile <ExtensionTable <TType> >();

        var underlyingItem = new ExtensionTable <TUnderlyingType> {
            Item = underlyingValue
        };
        var facadeItem = new ExtensionTable <TType> {
            Item = value
        };

        serializer.Serialize(facadeItem, destination);
        serializer.Serialize(underlyingItem, destination2);

        Assert.True(destination.AsSpan().SequenceEqual(destination2));

        var parsed = serializer.Parse <ExtensionTable <TType> >(destination);

        Assert.Equal(parsed.Item, value);
        Assert.Equal(serializer.GetMaxSize(facadeItem), serializer.GetMaxSize(underlyingItem));
    }
Esempio n. 10
0
 /// <summary>
 /// Creates a new FlatBufferSerializer using the given options.
 /// </summary>
 public FlatBufferSerializer(FlatBufferSerializerOptions options)
     : this(options, TypeModelContainer.CreateDefault())
 {
 }
Esempio n. 11
0
 public static bool TryResolve(string type, out ITypeModel builtInType)
 {
     return(TryResolve(type, TypeModelContainer.CreateDefault(), out builtInType));
 }
Esempio n. 12
0
    private void RunTest <T>(string fbsType, int length, FlatBufferDeserializationOption option) where T : struct
    {
        string schema = $@"
            {MetadataHelpers.AllAttributes}
            namespace StructVectorTests;

            table Table ({MetadataKeys.SerializerKind}) {{
                foo:Foo;
            }}
            struct Foo {{
              V:[{fbsType}:{length}];
            }}";

        (Assembly asm, string code) = FlatSharpCompiler.CompileAndLoadAssemblyWithCode(
            schema,
            new());

        Type tableType = asm.GetType("StructVectorTests.Table");
        Type fooType   = asm.GetType("StructVectorTests.Foo");
        var  typeModel = TypeModelContainer.CreateDefault().CreateTypeModel(fooType);

        Assert.Equal(FlatBufferSchemaType.Struct, typeModel.SchemaType);

        for (int i = 0; i < length; ++i)
        {
            PropertyInfo p = fooType.GetProperty($"__flatsharp__V_{i}", BindingFlags.Instance | BindingFlags.NonPublic);
            Assert.True(p.GetMethod.IsFamily);
            Assert.True(p.SetMethod.IsFamily);
            Assert.True(p.GetMethod.IsVirtual);
            Assert.True(p.SetMethod.IsVirtual);

            var metaAttr = p.GetCustomAttribute <FlatBufferMetadataAttribute>();
            var attr     = p.GetCustomAttribute <FlatBufferItemAttribute>();
            Assert.NotNull(attr);
            Assert.NotNull(metaAttr);
            Assert.Equal(i, attr.Index);
            Assert.Equal(FlatBufferMetadataKind.Accessor, metaAttr.Kind);
            Assert.Equal($"V[{attr.Index}]", metaAttr.Value);
        }

        var vectorProperty = fooType.GetProperty("V");

        Assert.Null(vectorProperty.GetCustomAttribute <FlatBufferItemAttribute>()); // pseudo-item, not actual.
        Assert.True(vectorProperty.GetMethod.IsPublic);
        Assert.False(vectorProperty.GetMethod.IsVirtual);
        Assert.Null(vectorProperty.SetMethod);

        dynamic table = Activator.CreateInstance(tableType);
        dynamic foo   = Activator.CreateInstance(fooType);

        table.foo = foo;

        Assert.Equal(length, foo.V.Count);

        // Test copyFrom with full array.
        List <T> items = new List <T>();

        for (int i = 0; i < length; ++i)
        {
            items.Add(GetRandom <T>());
        }

        table.foo.V.CopyFrom((IReadOnlyList <T>)items);
        for (int i = 0; i < length; ++i)
        {
            CheckRandom <T>(items[i], table.foo.V[i]);
        }

        for (int i = 0; i < length; ++i)
        {
            foo.V[i] = GetRandom <T>();
        }

        byte[] data = new byte[1024];

        var fbs = new FlatBufferSerializer(
            new FlatBufferSerializerOptions(option)
        {
            EnableAppDomainInterceptOnAssemblyLoad = true
        });

        var serializer = fbs.Compile((object)table);

        serializer.Write(data, (object)table);
        dynamic parsed = serializer.Parse(data);

        dynamic copy = Activator.CreateInstance(tableType, (object)parsed);

        Assert.Equal(length, parsed.foo.V.Count);
        for (int i = 0; i < length; ++i)
        {
            CheckRandom <T>(foo.V[i], parsed.foo.V[i]);
            CheckRandom <T>(foo.V[i], copy.foo.V[i]);
        }

        bool isMutable = option is FlatBufferDeserializationOption.GreedyMutable;

        if (length == 0)
        {
            return;
        }

        try
        {
            for (int i = 0; i < length; ++i)
            {
                parsed.foo.V[i] = GetRandom <T>();
            }

            Assert.True(isMutable);
        }
        catch (NotMutableException)
        {
            Assert.False(isMutable);
        }
    }
Esempio n. 13
0
        private void RunTest <T>(string fbsType, int length, FlatBufferDeserializationOption option) where T : struct
        {
            string schema = $@"
            namespace StructVectorTests;

            table Table ({MetadataKeys.SerializerKind}) {{
                foo:Foo;
            }}
            struct Foo {{
              V:[{fbsType}:{length}];
            }}";

            Assembly asm = FlatSharpCompiler.CompileAndLoadAssembly(
                schema,
                new());

            Type tableType = asm.GetType("StructVectorTests.Table");
            Type fooType   = asm.GetType("StructVectorTests.Foo");
            var  typeModel = TypeModelContainer.CreateDefault().CreateTypeModel(fooType);

            Assert.AreEqual(FlatBufferSchemaType.Struct, typeModel.SchemaType);

            for (int i = 0; i < length; ++i)
            {
                PropertyInfo p = fooType.GetProperty($"__flatsharp__V_{i}");
                Assert.IsTrue(p.GetMethod.IsPublic);
                Assert.IsTrue(p.SetMethod.IsPublic);
                Assert.IsTrue(p.GetMethod.IsVirtual);
                Assert.IsTrue(p.SetMethod.IsVirtual);

                var attr = p.GetCustomAttribute <FlatBufferItemAttribute>();
                Assert.IsNotNull(attr);
                Assert.AreEqual(i, attr.Index);

                var browsableAttr = p.GetCustomAttribute <EditorBrowsableAttribute>();
                Assert.IsNotNull(browsableAttr);
                Assert.AreEqual(EditorBrowsableState.Advanced, browsableAttr.State);
            }

            var vectorProperty = fooType.GetProperty("V");

            Assert.IsNull(vectorProperty.GetCustomAttribute <FlatBufferItemAttribute>()); // pseudo-item, not actual.
            Assert.IsNull(vectorProperty.GetCustomAttribute <EditorBrowsableAttribute>());
            Assert.IsTrue(vectorProperty.GetMethod.IsPublic);
            Assert.IsFalse(vectorProperty.GetMethod.IsVirtual);
            Assert.IsNull(vectorProperty.SetMethod);

            dynamic table = Activator.CreateInstance(tableType);
            dynamic foo   = Activator.CreateInstance(fooType);

            table.foo = foo;

            Assert.AreEqual(length, foo.V.Count);

            for (int i = 0; i < length; ++i)
            {
                foo.V[i] = GetRandom <T>();
            }

            byte[] data = new byte[1024];

            var fbs = new FlatBufferSerializer(
                new FlatBufferSerializerOptions(option)
            {
                EnableAppDomainInterceptOnAssemblyLoad = true
            });

            var serializer = fbs.Compile((object)table);

            serializer.Write(data, (object)table);
            dynamic parsed = serializer.Parse(data);

            dynamic copy = Activator.CreateInstance(tableType, (object)parsed);

            Assert.AreEqual(length, parsed.foo.V.Count);
            for (int i = 0; i < length; ++i)
            {
                CheckRandom <T>(foo.V[i], parsed.foo.V[i]);
                CheckRandom <T>(foo.V[i], copy.foo.V[i]);
            }

            bool isMutable = option is FlatBufferDeserializationOption.VectorCacheMutable or FlatBufferDeserializationOption.GreedyMutable;

            if (length == 0)
            {
                return;
            }

            try
            {
                for (int i = 0; i < length; ++i)
                {
                    parsed.foo.V[i] = GetRandom <T>();
                }

                Assert.IsTrue(isMutable);
            }
            catch (NotMutableException)
            {
                Assert.IsFalse(isMutable);
            }
        }
Esempio n. 14
0
 /// <summary>
 /// Gets or creates a runtime type model from the given type. This is only used in test cases any more.
 /// </summary>
 internal static ITypeModel CreateFrom(Type type)
 {
     return(TypeModelContainer.CreateDefault().CreateTypeModel(type));
 }