コード例 #1
0
        /// <summary>
        /// In lazy deserialization, FlatSharp reads from the underlying buffer each time. No caching is done. This will be
        /// the fastest option if your access patterns are sparse and you touch each element only once.
        /// </summary>
        public static void LazyDeserialization(DemoTable demo)
        {
            var serializer = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Lazy));

            byte[] buffer = new byte[1024];
            serializer.Serialize(demo, buffer);
            var parsed = serializer.Parse <DemoTable>(buffer);

            // Lazy deserialization reads objects from vectors each time you ask for them.
            InnerTable index0_1 = parsed.ListVector ![0];
コード例 #2
0
        public void TestInitialize()
        {
            var originalVector = new TableVector <string>
            {
                Vector = ExpectedStringContents.ToList()
            };

            var originalIntVector = new TableVector <int> {
                Vector = ExpectedIntContents.ToList()
            };

            Span <byte> buffer = new byte[1024];

            var serializer   = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Lazy));
            int bytesWritten = serializer.Serialize(originalVector, buffer);

            this.stringVector = serializer.Parse <TableVector <string> >(buffer.Slice(0, bytesWritten).ToArray());

            bytesWritten   = serializer.Serialize(originalIntVector, buffer);
            this.intVector = serializer.Parse <TableVector <int> >(buffer.Slice(0, bytesWritten).ToArray());
        }
コード例 #3
0
    public IndexedVectorTests()
    {
        this.stringVectorSource = new TableVector <string> {
            Vector = new IndexedVector <string, VectorMember <string> >()
        };
        this.intVectorSource = new TableVector <int> {
            Vector = new IndexedVector <int, VectorMember <int> >()
        };
        this.stringKeys = new List <string>();

        for (int i = 0; i < 10; ++i)
        {
            string key = i.ToString();
            stringKeys.Add(key);

            this.stringVectorSource.Vector.AddOrReplace(new VectorMember <string> {
                Key = key, Value = Guid.NewGuid().ToString()
            });
            this.intVectorSource.Vector.AddOrReplace(new VectorMember <int> {
                Key = i, Value = Guid.NewGuid().ToString()
            });
        }

        this.stringVectorSource.Vector.Freeze();
        this.intVectorSource.Vector.Freeze();

        Span <byte> buffer = new byte[1024];

        var serializer            = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Lazy));
        var progressiveSerializer = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Progressive));

        int bytesWritten = serializer.Serialize(this.stringVectorSource, buffer);

        this.stringVectorParsed      = serializer.Parse <TableVector <string> >(buffer.Slice(0, bytesWritten).ToArray());
        this.stringVectorProgressive = progressiveSerializer.Parse <TableVector <string> >(buffer.Slice(0, bytesWritten).ToArray());

        bytesWritten              = serializer.Serialize(this.intVectorSource, buffer);
        this.intVectorParsed      = serializer.Parse <TableVector <int> >(buffer.Slice(0, bytesWritten).ToArray());
        this.intVectorProgressive = progressiveSerializer.Parse <TableVector <int> >(buffer.Slice(0, bytesWritten).ToArray());
    }
コード例 #4
0
        public void TestInitialize()
        {
            var originalVector = new TableVector
            {
                StringVector = ExpectedContents.ToList()
            };

            Span <byte> buffer = new byte[1024];

            var serializer   = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Greedy));
            int bytesWritten = serializer.Serialize(originalVector, buffer);

            this.parsedVector = serializer.Parse <TableVector>(buffer.Slice(0, bytesWritten).ToArray());
        }
コード例 #5
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));
    }
コード例 #6
0
        /// <summary>
        /// Greedy deserialization operates the same way that conventional serializers do. The entire buffer is traversed
        /// and the structure is copied into the deserialized object. This is the most straightforward way of using FlatSharp,
        /// because the results it gives are predictable, and require no developer cognitive overhead. However, it can be less efficient
        /// in cases where you do not need to access all data in the buffer.
        /// </summary>
        public static void GreedyDeserialization(DemoTable demo)
        {
            // Same as FlatBufferSerializer.Default
            var serializer = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Greedy));

            byte[] buffer = new byte[1024];
            serializer.Serialize(demo, buffer);
            long originalSum = buffer.Sum(x => (long)x);

            var parsed = serializer.Parse <DemoTable>(buffer);

            // Fill array with 0. Source data is gone now, but we can still read the buffer because we were greedy!
            Array.Fill(buffer, (byte)0);

            InnerTable index0_1 = parsed.ListVector[0];
            InnerTable index0_2 = parsed.ListVector[0];

            Debug.Assert(object.ReferenceEquals(index0_1, index0_2), "Greedy deserialization returns you the same instance each time");

            // We cleared the data, but can still read the name. Greedy deserialization is easy!
            string name = parsed.Name;

            // By default, Flatsharp will not allow mutations to properties. You can learn more about this in the mutable example below.
            try
            {
                parsed.Name = "George Washington";
                Debug.Assert(false);
            }
            catch (NotMutableException)
            {
            }

            try
            {
                parsed.ListVector.Clear();
                Debug.Assert(false);
            }
            catch (NotSupportedException)
            {
            }
        }
コード例 #7
0
        public void SerializeDeserialize()
        {
            var factories = new List <Func <ByteBuffer, IFlatbufferObject> > {
                (data) => Data_8b.GetRootAsData_8b(data)
            };
            var serializer = new FlatBufferSerializer(factories);

            Data_8b original;
            {
                var builder = new FlatBufferBuilder(8);
                var offset  = Data_8b.CreateData_8b(builder);
                builder.Finish(offset.Value);
                original = Data_8b.GetRootAsData_8b(builder.DataBuffer);
            }

            var b            = serializer.Serialize(original);
            var deserialized = serializer.Deserialize <Data_8b>(b);

            Assert.Equal(original.Val1, deserialized.Val1);
            Assert.Equal(original.Val2, deserialized.Val2);
        }
コード例 #8
0
        private void RunSuccessTest <TTable, TStruct>()
            where TTable : class, IContextItem, IContextTable <TStruct>, new()
            where TStruct : class, IContextItem, new()
        {
            TTable table = new TTable();

            byte[] data = new byte[1024];

            foreach (FlatBufferDeserializationOption item in Enum.GetValues(typeof(FlatBufferDeserializationOption)))
            {
                var serializer = new FlatBufferSerializer(item);

                serializer.Serialize(table, data);
                TTable result = serializer.Parse <TTable>(data);

                Assert.IsNull(table.Context);
                Assert.AreEqual(item, result.Context.DeserializationOption);
                Assert.AreEqual(item, result.Struct.Context.DeserializationOption);
                Assert.IsFalse(object.ReferenceEquals(result.Context, result.Struct.Context));
            }
        }
コード例 #9
0
        /// <summary>
        /// This example shows GreedyMutable deserialization. This is exactly the same as Greedy deserialization, but setters are generated for
        /// the objects, so vectors and properties are mutable in a predictable way.
        /// </summary>
        public static void GreedyMutableDeserialization(DemoTable demo)
        {
            var serializer = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.GreedyMutable));

            byte[] buffer = new byte[1024];
            serializer.Serialize(demo, buffer);

            long originalSum = buffer.Sum(x => (long)x);

            var parsed = serializer.Parse <DemoTable>(buffer);

            parsed.Name = "James Adams";
            parsed.ListVector.Clear();
            parsed.ListVector.Add(new InnerTable());

            long newSum = buffer.Sum(x => (long)x);

            Debug.Assert(
                newSum == originalSum,
                "Changes to the deserialized objects are not written back to the buffer. You'll need to re-serialize it to a new buffer for that.");
        }
コード例 #10
0
        public void StringVector_GreedyDeserialize_NotMutable()
        {
            RootTable <IList <string> > root = new RootTable <IList <string> >
            {
                Vector = new List <string> {
                    "one", "two", "three"
                }
            };

            var options = new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Greedy);
            FlatBufferSerializer serializer = new FlatBufferSerializer(options);

            byte[] buffer = new byte[100];
            serializer.Serialize(root, buffer);

            var parsed = serializer.Parse <RootTable <IList <string> > >(buffer);

            Assert.AreEqual(typeof(ReadOnlyCollection <string>), parsed.Vector.GetType());
            Assert.IsTrue(parsed.Vector.IsReadOnly);

            Assert.ThrowsException <NotSupportedException>(() => parsed.Vector.Add("four"));
        }
コード例 #11
0
        public void StringVector_GreedyDeserialize_Mutable()
        {
            RootTable <IList <string> > root = new RootTable <IList <string> >
            {
                Vector = new List <string> {
                    "one", "two", "three"
                }
            };

            var options = new FlatBufferSerializerOptions(FlatBufferDeserializationOption.GreedyMutable);
            FlatBufferSerializer serializer = new FlatBufferSerializer(options);

            byte[] buffer = new byte[100];
            serializer.Serialize(root, buffer);

            var parsed = serializer.Parse <RootTable <IList <string> > >(buffer);

            Assert.AreEqual(typeof(List <string>), parsed.Vector.GetType());
            Assert.IsFalse(parsed.Vector.IsReadOnly);

            // Shouldn't throw.
            parsed.Vector.Add("four");
        }
コード例 #12
0
        /// <summary>
        /// The next step up in greediness is PropertyCache mode. In this mode, Flatsharp will cache the results of property accesses.
        /// So, if you read the results of FooObject.Property1 multiple times, the same value comes back each time. What this mode
        /// does not do is cache vectors. So reding FooObject.Vector[0] multiple times re-visits the buffer each time.
        /// </summary>
        public static void PropertyCacheDeserialization(DemoTable demo)
        {
            var serializer = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.PropertyCache));

            byte[] buffer = new byte[1024];
            serializer.Serialize(demo, buffer);
            var parsed = serializer.Parse <DemoTable>(buffer);

            // Properties from tables and structs are cached after they are read.
            string name  = parsed.Name;
            string name2 = parsed.Name;

            Debug.Assert(
                object.ReferenceEquals(name, name2),
                "When reading table/struct properties, PropertyCache mode returns the same instance.");

            // PropertyCache deserialization doesn't cache the results of vector lookups.
            InnerTable index0_1 = parsed.ListVector[0];
            InnerTable index0_2 = parsed.ListVector[0];

            Debug.Assert(!object.ReferenceEquals(index0_1, index0_2), "A different instance is returned each time from vectors in PropertyCache mode.");
            Debug.Assert(object.ReferenceEquals(parsed.ListVector, parsed.ListVector), "But the vector instance itself is the cached.");
            Debug.Assert(object.ReferenceEquals(index0_1.Fruit, index0_1.Fruit), "And the items returned from each vector exhibit property cache behavior");

            // Invalidate the whole buffer. Undefined behavior past here!
            Array.Fill(buffer, (byte)0);

            try
            {
                var whoKnows = parsed.ListVector[1];
                Debug.Assert(false);
            }
            catch
            {
                // This can be any sort of exception. This behavior is undefined.
            }
        }
コード例 #13
0
        /// <summary>
        /// Vector cache is a superset of PropertyCache. The difference is that when deserializing in VectorCache mode, FlatSharp
        /// will allocate a vector for you that gets lazily filled in as elements are accessed. This leads to some array allocations
        /// behind the scenes, since FlatSharp needs to know what objects have been returned for what indices.
        /// </summary>
        public static void VectorCacheDeserialization(DemoTable demo)
        {
            var serializer = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.VectorCache));

            byte[] buffer = new byte[1024];
            serializer.Serialize(demo, buffer);
            var parsed = serializer.Parse <DemoTable>(buffer);

            // Properties from tables and structs are cached after they are read.
            string name  = parsed.Name;
            string name2 = parsed.Name;

            Debug.Assert(
                object.ReferenceEquals(name, name2),
                "When reading table/struct properties, PropertyCache mode returns the same instance.");

            // VectorCache deserialization guarantees only one object per index.
            InnerTable index0_1 = parsed.ListVector[0];
            InnerTable index0_2 = parsed.ListVector[0];

            Debug.Assert(object.ReferenceEquals(index0_1, index0_2), "The same instance is returned each time from vectors in VectorCache mode.");
            Debug.Assert(object.ReferenceEquals(parsed.ListVector, parsed.ListVector), "And the vector instance itself is the same.");
            Debug.Assert(object.ReferenceEquals(index0_1.Fruit, index0_1.Fruit), "And the items returned from each vector exhibit property cache behavior");
        }
コード例 #14
0
            static void Test(FlatBufferDeserializationOption option)
            {
                var table = new Table <WriteThroughStruct>
                {
                    Struct = new WriteThroughStruct
                    {
                        Value = new OtherStruct {
                            Prop1 = 10, Prop2 = 10
                        },
                        ValueStruct = new() { Value = 3, }
                    }
                };

                FlatBufferSerializer serializer = new FlatBufferSerializer(option);

                byte[] buffer = new byte[1024];
                serializer.Serialize(table, buffer);

                // parse
                var parsed1 = serializer.Parse <Table <WriteThroughStruct> >(buffer);

                // mutate
                Assert.Equal(10, parsed1.Struct.Value.Prop1);
                Assert.Equal(10, parsed1.Struct.Value.Prop2);
                Assert.Equal(3, parsed1.Struct.ValueStruct.Value);
                parsed1.Struct.Value = new OtherStruct {
                    Prop1 = 300, Prop2 = 300
                };
                parsed1.Struct.ValueStruct = new() { Value = -1 };
                Assert.Equal(300, parsed1.Struct.Value.Prop1);
                Assert.Equal(300, parsed1.Struct.Value.Prop2);
                Assert.Equal(-1, parsed1.Struct.ValueStruct.Value);

                // verify, set to null
                var parsed2 = serializer.Parse <Table <WriteThroughStruct> >(buffer);

                Assert.Equal(300, parsed2.Struct.Value.Prop1);
                Assert.Equal(300, parsed2.Struct.Value.Prop2);
                Assert.Equal(-1, parsed2.Struct.ValueStruct.Value);
                parsed2.Struct.Value = null !;

                if (option == FlatBufferDeserializationOption.Progressive)
                {
                    // we are null temporarily until we re-parse.
                    Assert.Null(parsed2.Struct.Value);
                }
                else if (option == FlatBufferDeserializationOption.Lazy)
                {
                    // lazy write through clears it out.
                    Assert.Equal(0, parsed2.Struct.Value.Prop1);
                    Assert.Equal(0, parsed2.Struct.Value.Prop2);
                }
                else
                {
                    Assert.False(true);
                }

                // verify, set to null
                var parsed3 = serializer.Parse <Table <WriteThroughStruct> >(buffer);

                Assert.Equal(0, parsed3.Struct.Value.Prop1);
                Assert.Equal(0, parsed3.Struct.Value.Prop2);
            }

            Test(FlatBufferDeserializationOption.Progressive);
            Test(FlatBufferDeserializationOption.Lazy);
        }
コード例 #15
0
    private void TestType <T>(FlatBufferDeserializationOption option, Func <T> generator) where T : IEquatable <T>
    {
        var options = new FlatBufferSerializerOptions(option);
        FlatBufferSerializer serializer = new FlatBufferSerializer(options);

        {
            var memoryTable = new RootTable <IList <T> >
            {
                Vector = Enumerable.Range(0, 10).Select(i => generator()).ToArray()
            };

            Span <byte> memory            = new byte[10240];
            int         offset            = serializer.Serialize(memoryTable, memory);
            var         memoryTableResult = serializer.Parse <RootTable <IList <T> > >(memory.Slice(0, offset).ToArray());

            var resultVector = memoryTableResult.Vector;
            for (int i = 0; i < memoryTableResult.Vector.Count; ++i)
            {
                Assert.Equal <T>(memoryTable.Vector[i], resultVector[i]);

                // reference equality should correspond to the serializer.
                Assert.Equal(option != FlatBufferDeserializationOption.Lazy, object.ReferenceEquals(resultVector[i], resultVector[i]));
            }
        }

        {
            var memoryTable = new RootTable <IReadOnlyList <T> >
            {
                Vector = Enumerable.Range(0, 10).Select(i => generator()).ToArray()
            };

            Span <byte> memory            = new byte[10240];
            int         offset            = serializer.Serialize(memoryTable, memory);
            var         memoryTableResult = serializer.Parse <RootTable <IReadOnlyList <T> > >(memory.Slice(0, offset).ToArray());
            var         resultVector      = memoryTableResult.Vector;
            for (int i = 0; i < memoryTableResult.Vector.Count; ++i)
            {
                Assert.Equal(memoryTable.Vector[i], resultVector[i]);

                // reference equality should correspond to the serializer.
                Assert.Equal(option != FlatBufferDeserializationOption.Lazy, object.ReferenceEquals(resultVector[i], resultVector[i]));
            }
        }

        if (option != FlatBufferDeserializationOption.Lazy && option != FlatBufferDeserializationOption.Progressive)
        {
            var memoryTable = new RootTable <T[]>
            {
                Vector = Enumerable.Range(0, 10).Select(i => generator()).ToArray()
            };

            Span <byte> memory            = new byte[10240];
            int         offset            = serializer.Serialize(memoryTable, memory);
            var         memoryTableResult = serializer.Parse <RootTable <T[]> >(memory.Slice(0, offset).ToArray());
            var         resultVector      = memoryTableResult.Vector;
            for (int i = 0; i < memoryTableResult.Vector.Length; ++i)
            {
                Assert.Equal(memoryTable.Vector[i], resultVector[i]);
            }
        }
    }
コード例 #16
0
        public static void SaveGame(String pathToFolder, NamelessGame game)
        {
            var  saveFile = new NamelessRogueSaveFile();
            Type iStorageInterfaceType = typeof(IStorage <>);

            foreach (var componentTypeCollection in EntityInfrastructureManager.Components)
            {
                if (componentTypeCollection.Key.GetCustomAttributes(true).Any(a => a.GetType() == typeof(NamelessRogue.Engine.Serialization.SkipClassGeneration)))
                {
                    continue;
                }

                foreach (var componentDictionary in componentTypeCollection.Value)
                {
                    //the type of the storage that can store current type
                    Type storageType = saveFile.ComponentTypeToStorge[componentTypeCollection.Key];

                    var constructor = storageType.GetConstructor(Type.EmptyTypes);
                    if (constructor == null)
                    {
                        throw new Exception($@"{storageType.Name} must contain a parameterless constructor in order for Save manager to serialize it");
                    }

                    dynamic storageObject = constructor.Invoke(null);

                    storageObject.FillFrom(ObjectExtensions.CastToReflected(componentDictionary.Value, componentDictionary.Value.GetType()));

                    saveFile.StoragesDictionary[storageObject.GetType()].Add(storageObject);
                }
            }
            foreach (var entity in EntityInfrastructureManager.Entities.Values)
            {
                var storage = new EntityStorage();
                storage.FillFrom(entity);
                saveFile.EntityStorageTable.Add(storage);
            }

            {
                int    maxBytesNeeded = FlatBufferSerializer.Default.GetMaxSize(saveFile);
                byte[] buffer         = new byte[maxBytesNeeded];
                int    bytesWritten   = FlatBufferSerializer.Default.Serialize(saveFile, buffer);

                var stream = File.OpenWrite("objectdata.nrs");
                stream.Write(buffer, 0, bytesWritten);
                stream.Close();
            }

            {
                TimelineStorage timelinesStorage = new TimelineStorage();
                var             timeline         = game.TimelineEntity.GetComponentOfType <TimeLine>();
                timelinesStorage.FillFrom(timeline);
                {
                    FlatBufferSerializer serializer = new FlatBufferSerializer(FlatBufferDeserializationOption.Greedy);
                    int maxBytesNeeded = serializer.GetMaxSize(timelinesStorage);

                    int byteNeeded = serializer.GetMaxSize(timelinesStorage.CurrentTimelineLayer.WorldTiles[50 * 10]);

                    byte[] buffer = new byte[maxBytesNeeded];

                    int bytesWritten = serializer.Serialize(timelinesStorage, buffer);

                    var stream = File.OpenWrite("chunksmemory.nrs");
                    stream.Write(buffer, 0, bytesWritten);
                    stream.Close();
                }
            }
        }
コード例 #17
0
        public static void Run()
        {
            FooBarContainer container = new FooBarContainer
            {
                fruit       = Fruit.Pears,
                initialized = true,
                location    = "location",
                list        = new List <FooBar>
                {
                    new FooBar
                    {
                        name    = "name",
                        postfix = 1,
                        rating  = 3,
                        sibling = new Bar
                        {
                            ratio = 3.14f,
                            size  = ushort.MaxValue,
                            time  = int.MinValue,

                            // Nested structs are not intended to have null values,
                            // but it is possible due to FlatSharp modeling
                            // them as reference types. However, null structs
                            // do not cause a problem when serializing or parsing.
                            parent = null !,
                        }
                    }
                },
            };

            // Simple use case: make a deep copy of an object you're using.
            var copy = new FooBarContainer(container);

            Debug.Assert(!object.ReferenceEquals(copy.list, container.list), "A new list is created");
            for (int i = 0; i < container.list.Count; ++i)
            {
                var originalItem = container.list[i];

                Debug.Assert(copy.list is not null);
                var copyItem = copy.list[i];
                Debug.Assert(!object.ReferenceEquals(copyItem, originalItem));
            }

            // Now let's look at how this can be useful when operating on deserialized objects.
            var serializer = new FlatBufferSerializer(FlatBufferDeserializationOption.Lazy);

            byte[] data = new byte[1024];
            serializer.Serialize(container, data);
            var deserialized = serializer.Parse <FooBarContainer>(data);

            // Take a deserialized item and "upcast" it back to the original type.
            // This performs a full traversal of the object and allows the underlying buffer to be reused.
            Debug.Assert(deserialized.GetType() != container.GetType(), "The deserialized type is a subclass of the FooBarContainer type");
            copy = new FooBarContainer(deserialized);
            Debug.Assert(copy.GetType() == container.GetType(), "By using the copy constructor, we can get an instance of the original type.");

            // Next: Some deserialization modes, such as Lazy, don't permit mutation of the object.
            // Using the copy constructor can convert this to an object that we can mutate!
            try
            {
                // will throw
                deserialized.fruit = Fruit.Apples;
                Debug.Assert(false);
            }
            catch
            {
            }

            // Modifying the copy is just fine, though.
            copy.fruit = Fruit.Apples;
        }
コード例 #18
0
        static void Main(string[] args)
        {
            Upstream up = new Upstream();

            up.Structure      = new FSeed();
            up.Structure.Data = new ConfigEntry[1];
            var e0 = new ConfigEntry();

            up.Structure.Data[0] = e0;
            e0.Tag  = "stuff";
            e0.Type = "string";
            e0.Used = true;

            Console.WriteLine("test serializing up");

            var testBuffer = new byte[1000];

            var serializer = new FlatBufferSerializer(new FlatBufferSerializerOptions(FlatBufferDeserializationOption.Default));

            var testLength = serializer.Serialize(up, testBuffer);

            Upstream up2 = serializer.Parse <Upstream>(testBuffer);


            Console.WriteLine("Starting Main");

            // For some reason, I have to copy the args into a local array, or else they disappear
            int[] fileDescriptors = new int[2];
            for (int i = 0; i < fileDescriptors.Length && i < args.Length; i++)
            {
                int n = ParsedFd(args[i]);
                Console.WriteLine(n);
                fileDescriptors[i] = n;
            }

            // Grab the FDs from the environment variables and translate to a IntPtr
            int            fdNumIn      = fileDescriptors[0];
            SafeFileHandle inPipeHandle = new SafeFileHandle(new IntPtr(fdNumIn), true);

            int            fdNumOut      = fileDescriptors[1];
            SafeFileHandle outPipeHandle = new SafeFileHandle(new IntPtr(fdNumOut), true);

            Console.WriteLine("GO_FUZZ_IN_FD: " + fdNumIn);
            Console.WriteLine("GO_FUZZ_OUT_FD: " + fdNumOut);

            string[] commName = new string[4];
            for (int i = 2; i < args.Length; i++)
            {
                commName[i - 2] = args[i];
                Console.WriteLine(("comm" + (i - 2)) + ": " + commName[(i - 2)]);
            }

            const int MaxInputSize     = 1 << 24;
            const int ReturnResultSize = 1 << 25;
            const int CoverSize        = 64 << 10;
            const int SonarRegionSize  = 1 << 20;

            // Use the filehandles
            Stream inStream = new FileStream(inPipeHandle, FileAccess.Read);

            Console.WriteLine("created inStream");
            Stream outStream = new FileStream(outPipeHandle, FileAccess.Write);

            Console.WriteLine("created outStream");

            MemoryMappedFileSecurity security = new MemoryMappedFileSecurity();

            security.AddAccessRule(new AccessRule <MemoryMappedFileRights>(("Everyone"), MemoryMappedFileRights.FullControl, AccessControlType.Allow));

            Console.WriteLine("created security");

            MemoryMappedFile comm0 = MemoryMappedFile.OpenExisting(commName[0], MemoryMappedFileRights.ReadWrite, HandleInheritability.Inheritable);

            Console.WriteLine("created comm0");
            var comm0Accessor = comm0.CreateViewAccessor(0, MaxInputSize);

            Console.WriteLine("created comm0Accessor");

            MemoryMappedFile comm1 = MemoryMappedFile.OpenExisting(commName[1], MemoryMappedFileRights.ReadWrite, HandleInheritability.Inheritable);

            Console.WriteLine("created comm1");
            var comm1Accessor = comm1.CreateViewAccessor(0, ReturnResultSize);

            Console.WriteLine("created comm1Accessor");

            MemoryMappedFile comm2 = MemoryMappedFile.OpenExisting(commName[2], MemoryMappedFileRights.ReadWrite, HandleInheritability.Inheritable);

            Console.WriteLine("created comm2");
            var comm2Accessor = comm2.CreateViewAccessor(0, CoverSize);

            Console.WriteLine("created comm2Accessor");

            //var comm3Stream = new FileStream(commNames[3], FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
            //Console.WriteLine("created comm3Stream");
            MemoryMappedFile comm3 = MemoryMappedFile.OpenExisting(commName[3], MemoryMappedFileRights.ReadWrite, HandleInheritability.Inheritable);

            Console.WriteLine("created comm3");
            var comm3Accessor = comm3.CreateViewAccessor(0, SonarRegionSize);

            Console.WriteLine("created comm3Accessor");

            char[] inPipeBuffer       = new char[10];
            char[] outputBuffer       = new char[24];
            char[] returnLengthBuffer = new char[8];

            StreamReader inPipeReader = new StreamReader(inStream);
            StreamWriter outputWriter = new StreamWriter(outStream);

            while (true)
            {
                inPipeReader.Read(inPipeBuffer, 0, inPipeBuffer.Length);

                int fnidx = inPipeBuffer[0];
                fnidx += inPipeBuffer[1] << 8;
                Console.WriteLine("fnidx: " + fnidx);

                char[] lengthBuffer = new char[8];
                for (int i = 2; i < inPipeBuffer.Length; i++)
                {
                    lengthBuffer[i - 2] = inPipeBuffer[i];
                }
                Int64 inputLength = Deserialize64(lengthBuffer);
                Console.WriteLine("input length: " + inputLength);

                // read inputBuffer data from comm0
                var inputBuffer = new byte[inputLength];
                comm0Accessor.ReadArray(0, inputBuffer, 0, (int)inputLength);
                for (int i = 0; i < inputLength; i++)
                {
                    inputBuffer[i] = comm0Accessor.ReadByte(i);
                }

                var inputString = Encoding.UTF8.GetString(inputBuffer);

                Console.WriteLine("downstream: ");
                Console.WriteLine(inputString);

                //var downstream = Downstream.Deserialize(inputString);
                var downstream = FlatBufferSerializer.Default.Parse <Downstream>(inputBuffer);
                Console.WriteLine("downstream deserialized");

                var         seed    = downstream.Seed;
                var         entries = seed.Data;
                ConfigEntry entry   = null;
                if (entries.Count >= 1)
                {
                    entry = entries[0];
                }
                else
                {
                    Console.WriteLine("zero entries!");
                }

                var value = entry.Value;
                Console.WriteLine("got entry value: " + value);

                Int64 res = 0;
                Int64 ns;
                Int64 sonar        = 0;
                Int64 returnLength = 0;

                // Start the clock
                var nsStart = DateTime.UtcNow.Ticks;

                // Actually run the function to fuzz
                Console.WriteLine("BrokenMethod()");
                Console.WriteLine(BrokenMethod(value));

                ns = DateTime.UtcNow.Ticks - nsStart;
                Console.WriteLine("ns: " + ns);

                char[] resBuffer   = new char[8];
                char[] nsBuffer    = new char[8];
                char[] sonarBuffer = new char[8];

                Serialize56(resBuffer, res);
                Serialize56(nsBuffer, ns);
                Serialize56(sonarBuffer, sonar);

                Console.WriteLine("instantiating upstream");

                Upstream upstream = new Upstream();
                upstream.Structure      = new FSeed();
                upstream.Structure.Data = new ConfigEntry[1];
                var upEntry = upstream.Structure.Data[0];
                upEntry.Tag  = "stuff";
                upEntry.Type = "string";
                upEntry.Used = true;

                Console.WriteLine("serializing upstream");

                int maxReturnSize = FlatBufferSerializer.Default.GetMaxSize(upstream);
                var returnBuffer  = new byte[maxReturnSize];
                returnLength = FlatBufferSerializer.Default.Serialize(upstream, returnBuffer);
                Console.WriteLine("return length: " + returnLength);
                Serialize56(returnLengthBuffer, returnLength);

                for (int i = 0; i < 8; i++)
                {
                    Console.WriteLine("returnLengthBuffer: " + (byte)returnLengthBuffer[i]);
                    comm1Accessor.Write(i, returnLengthBuffer[i]);
                }

                for (int i = 0; i < returnLength; i++)
                {
                    comm1Accessor.Write(i + 8, returnBuffer[i]);
                }

                comm1Accessor.Flush();
                Console.WriteLine("wrote to comm1Accessor");

                for (int i = 0; i < 8; i++)
                {
                    outputBuffer[i]      = resBuffer[i];
                    outputBuffer[i + 8]  = nsBuffer[i];
                    outputBuffer[i + 16] = sonarBuffer[i];
                }

                outputWriter.Write(outputBuffer, 0, outputBuffer.Length);
                outputWriter.Flush();
                Console.WriteLine("wrote outputbuffer");
            }
        }