<|start_filename|>FlexBuffers/FlexBufferBuilder.cs<|end_filename|>
using System;
using System.Runtime.InteropServices;

namespace FlexBuffers
{
    public class FlexBufferBuilder
    {
        public static byte[] Map(Action<IFlexBufferMapBuilder> map)
        {
            var buffer = new FlexBuffer();
            var start = buffer.StartVector();
            var builder = new FlexBufferMapBuilder(buffer);
            map(builder);
            buffer.SortAndEndMap(start);
            return buffer.Finish();
        }
        
        public static byte[] Vector(Action<IFlexBufferVectorBuilder> vector)
        {
            var buffer = new FlexBuffer();
            var start = buffer.StartVector();
            var builder = new FlexBufferVectorBuilder(buffer);
            vector(builder);
            buffer.EndVector(start, false, false);
            return buffer.Finish();
        }
    }

    public interface IFlexBufferMapBuilder
    {
        void AddNull(string key);
        void Add(string key, long value, bool indirect = false);
        void Add(string key, long x, long y);
        void Add(string key, long x, long y, long z);
        void Add(string key, long x, long y, long z, long w);
        void Add(string key, ulong value, bool indirect = false);
        void Add(string key, ulong x, ulong y);
        void Add(string key, ulong x, ulong y, ulong z);
        void Add(string key, ulong x, ulong y, ulong z, ulong w);
        void Add(string key, double value, bool indirect = false);
        void Add(string key, double x, double y);
        void Add(string key, double x, double y, double z);
        void Add(string key, double x, double y, double z, double w);
        void Add(string key, bool value);
        void Add(string key, string value);
        void Add(string key, byte[] value);
        void Map(string key, Action<IFlexBufferMapBuilder> map);
        void Vector(string key, Action<IFlexBufferVectorBuilder> vector);
    }
    
    public interface IFlexBufferVectorBuilder
    {
        void AddNull();
        void Add(long value, bool indirect = false);
        void Add(long x, long y);
        void Add(long x, long y, long z);
        void Add(long x, long y, long z, long w);
        void Add(ulong value, bool indirect = false);
        void Add(ulong x, ulong y);
        void Add(ulong x, ulong y, ulong z);
        void Add(ulong x, ulong y, ulong z, ulong w);
        void Add(double value, bool indirect = false);
        void Add(double x, double y);
        void Add(double x, double y, double z);
        void Add(double x, double y, double z, double w);
        void Add(bool value);
        void Add(string value);
        void Add(byte[] value);
        void Map(Action<IFlexBufferMapBuilder> map);
        void Vector(Action<IFlexBufferVectorBuilder> vector);
    }

    internal struct FlexBufferMapBuilder : IFlexBufferMapBuilder
    {
        private readonly FlexBuffer _buffer;

        internal FlexBufferMapBuilder(FlexBuffer buffer)
        {
            _buffer = buffer;
        }

        public void AddNull(string key)
        {
            _buffer.AddKey(key);
            _buffer.AddNull();
        }
        
        public void Add(string key, long value, bool indirect = false)
        {
            _buffer.AddKey(key);
            if (indirect)
            {
                _buffer.AddIndirect(value);
            }
            else
            {
                _buffer.Add(value);
            }
        }

        public void Add(string key, long x, long y)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, long x, long y, long z)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, long x, long y, long z, long w)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.Add(w);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, ulong value, bool indirect = false)
        {
            _buffer.AddKey(key);
            if (indirect)
            {
                _buffer.AddIndirect(value);
            }
            else
            {
                _buffer.Add(value);
            }
        }

        public void Add(string key, ulong x, ulong y)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, ulong x, ulong y, ulong z)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, ulong x, ulong y, ulong z, ulong w)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.Add(w);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, double value, bool indirect = false)
        {
            _buffer.AddKey(key);
            if (indirect)
            {
                _buffer.AddIndirect(value);
            }
            else
            {
                _buffer.Add(value);
            }
        }

        public void Add(string key, double x, double y)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, double x, double y, double z)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, double x, double y, double z, double w)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.Add(w);
            _buffer.EndVector(start, true, true);
        }

        public void Add(string key, bool value)
        {
            _buffer.AddKey(key);
            _buffer.Add(value);
        }

        public void Add(string key, string value)
        {
            _buffer.AddKey(key);
            _buffer.Add(value);
        }

        public void Add(string key, byte[] value)
        {
            _buffer.AddKey(key);
            _buffer.Add(value);
        }

        public void Map(string key, Action<IFlexBufferMapBuilder> map)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            var builder = new FlexBufferMapBuilder(_buffer);
            map(builder);
            _buffer.SortAndEndMap(start);
        }

        public void Vector(string key, Action<IFlexBufferVectorBuilder> vector)
        {
            _buffer.AddKey(key);
            var start = _buffer.StartVector();
            var builder = new FlexBufferVectorBuilder(_buffer);
            vector(builder);
            _buffer.EndVector(start, false, false);
        }
    }

    internal struct FlexBufferVectorBuilder : IFlexBufferVectorBuilder
    {
        private readonly FlexBuffer _buffer;

        internal FlexBufferVectorBuilder(FlexBuffer buffer)
        {
            _buffer = buffer;
        }

        public void AddNull()
        {
            _buffer.AddNull();
        }
        public void Add(long value, bool indirect = false)
        {
            if (indirect)
            {
                _buffer.AddIndirect(value);
            }
            else
            {
                _buffer.Add(value);
            }
        }

        public void Add(long x, long y)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.EndVector(start, true, true);
        }

        public void Add(long x, long y, long z)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.EndVector(start, true, true);
        }

        public void Add(long x, long y, long z, long w)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.Add(w);
            _buffer.EndVector(start, true, true);
        }

        public void Add(ulong value, bool indirect = false)
        {
            if (indirect)
            {
                _buffer.AddIndirect(value);
            }
            else
            {
                _buffer.Add(value);
            }
        }

        public void Add(ulong x, ulong y)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.EndVector(start, true, true);
        }

        public void Add(ulong x, ulong y, ulong z)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.EndVector(start, true, true);
        }

        public void Add(ulong x, ulong y, ulong z, ulong w)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.Add(w);
            _buffer.EndVector(start, true, true);
        }

        public void Add(double value, bool indirect = false)
        {
            if (indirect)
            {
                _buffer.AddIndirect(value);
            }
            else
            {
                _buffer.Add(value);
            }
        }

        public void Add(double x, double y)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.EndVector(start, true, true);
        }

        public void Add(double x, double y, double z)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.EndVector(start, true, true);
        }

        public void Add(double x, double y, double z, double w)
        {
            var start = _buffer.StartVector();
            _buffer.Add(x);
            _buffer.Add(y);
            _buffer.Add(z);
            _buffer.Add(w);
            _buffer.EndVector(start, true, true);
        }

        public void Add(bool value)
        {
            _buffer.Add(value);
        }

        public void Add(string value)
        {
            _buffer.Add(value);
        }

        public void Add(byte[] value)
        {
            _buffer.Add(value);
        }

        public void Map(Action<IFlexBufferMapBuilder> map)
        {
            var start = _buffer.StartVector();
            var builder = new FlexBufferMapBuilder(_buffer);
            map(builder);
            _buffer.SortAndEndMap(start);
        }

        public void Vector(Action<IFlexBufferVectorBuilder> vector)
        {
            var start = _buffer.StartVector();
            var builder = new FlexBufferVectorBuilder(_buffer);
            vector(builder);
            _buffer.EndVector(start, false, false);
        }
    }
}

<|start_filename|>FlexBuffersCSharpTests/CsvToFlexBuffersConverterTests.cs<|end_filename|>
using FlexBuffers;
using NUnit.Framework;

namespace FlexBuffersCSharpTests
{
    [TestFixture]
    public class CsvToFlexBuffersConverterTests
    {
        [Test]
        public void SimpleCSV()
        {
            var bytes = CsvToFlexBufferConverter.Convert("A,B,C");
            var flx = FlxValue.FromBytes(bytes);
            Assert.AreEqual(flx.AsVector.Length, 1);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
        }
        
        [Test]
        public void SimpleCSVWithEmptyValue()
        {
            var bytes = CsvToFlexBufferConverter.Convert("A,,C");
            var flx = FlxValue.FromBytes(bytes);
            Assert.AreEqual(flx.AsVector.Length, 1);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "");
            Assert.AreEqual(flx[0][2].AsString, "C");
        }
        
        [Test]
        public void SimpleCSVWithRN()
        {
            var bytes = CsvToFlexBufferConverter.Convert("A,B,C\r\n1,2,3");
            var flx = FlxValue.FromBytes(bytes);
            Assert.AreEqual(flx.AsVector.Length, 2);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
            
            Assert.AreEqual(flx[1].AsVector.Length, 3);
            Assert.AreEqual(flx[1][0].AsString, "1");
            Assert.AreEqual(flx[1][1].AsString, "2");
            Assert.AreEqual(flx[1][2].AsString, "3");
        }
        
        [Test]
        public void MultipleLineCSV()
        {
            var bytes = CsvToFlexBufferConverter.Convert(
@"A,B,C
1,2,3
dskfsdh,sdfsdf,sdfsf");
            var flx = FlxValue.FromBytes(bytes);
            var json = flx.ToJson;
            Assert.AreEqual(flx.AsVector.Length, 3);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
            
            Assert.AreEqual(flx[1][0].AsString, "1");
            Assert.AreEqual(flx[1][1].AsString, "2");
            Assert.AreEqual(flx[1][2].AsString, "3");
            
            Assert.AreEqual(flx[2][0].AsString, "dskfsdh");
            Assert.AreEqual(flx[2][1].AsString, "sdfsdf");
            Assert.AreEqual(flx[2][2].AsString, "sdfsf");
        }
        
        [Test]
        public void MultipleLineWithNewLineAtTheEndCSV()
        {
            var bytes = CsvToFlexBufferConverter.Convert(
@"A,B,C
1,2,3
dskfsdh,sdfsdf,sdfsf
");
            var flx = FlxValue.FromBytes(bytes);
            var json = flx.ToJson;
            Assert.AreEqual(flx.AsVector.Length, 3);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
            
            Assert.AreEqual(flx[1][0].AsString, "1");
            Assert.AreEqual(flx[1][1].AsString, "2");
            Assert.AreEqual(flx[1][2].AsString, "3");
            
            Assert.AreEqual(flx[2][0].AsString, "dskfsdh");
            Assert.AreEqual(flx[2][1].AsString, "sdfsdf");
            Assert.AreEqual(flx[2][2].AsString, "sdfsf");
        }
        
        [Test]
        public void MultipleLineWithDoubleQuotes()
        {
            var bytes = CsvToFlexBufferConverter.Convert(
                @"A,B,C
1,2,3
""dskfsdh"",sdfsdf,sdfsf
");
            var flx = FlxValue.FromBytes(bytes);
            var json = flx.ToJson;
            Assert.AreEqual(flx.AsVector.Length, 3);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
            
            Assert.AreEqual(flx[1][0].AsString, "1");
            Assert.AreEqual(flx[1][1].AsString, "2");
            Assert.AreEqual(flx[1][2].AsString, "3");
            
            Assert.AreEqual(flx[2][0].AsString, "dskfsdh");
            Assert.AreEqual(flx[2][1].AsString, "sdfsdf");
            Assert.AreEqual(flx[2][2].AsString, "sdfsf");
        }
        
        [Test]
        public void MultipleLineWithDoubleQuotesEscapingComma()
        {
            var bytes = CsvToFlexBufferConverter.Convert(
                @"A,B,C
1,2,3
""ds,kfs,dh"",sdfsdf,sdfsf
");
            var flx = FlxValue.FromBytes(bytes);
            var json = flx.ToJson;
            Assert.AreEqual(flx.AsVector.Length, 3);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
            
            Assert.AreEqual(flx[1][0].AsString, "1");
            Assert.AreEqual(flx[1][1].AsString, "2");
            Assert.AreEqual(flx[1][2].AsString, "3");
            
            Assert.AreEqual(flx[2][0].AsString, "ds,kfs,dh");
            Assert.AreEqual(flx[2][1].AsString, "sdfsdf");
            Assert.AreEqual(flx[2][2].AsString, "sdfsf");
        }
        
        [Test]
        public void MultipleLineWithDoubleQuotesEscapingDoubleQuotes()
        {
            var bytes = CsvToFlexBufferConverter.Convert(
                @"A,B,C
1,2,3
""ds""""kfsdh"",sdfsdf,sdfsf
");
            var flx = FlxValue.FromBytes(bytes);
            var json = flx.ToJson;
            Assert.AreEqual(flx.AsVector.Length, 3);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
            
            Assert.AreEqual(flx[1][0].AsString, "1");
            Assert.AreEqual(flx[1][1].AsString, "2");
            Assert.AreEqual(flx[1][2].AsString, "3");
            
            Assert.AreEqual(flx[2][0].AsString, "ds\"kfsdh");
            Assert.AreEqual(flx[2][1].AsString, "sdfsdf");
            Assert.AreEqual(flx[2][2].AsString, "sdfsf");
        }
        
        [Test]
        public void MultipleLineWithDoubleQuotesEscapingLineBreak()
        {
            var bytes = CsvToFlexBufferConverter.Convert(
                @"A,B,C
1,2,3
""ds
kfsdh"",sdfsdf,sdfsf
");
            var flx = FlxValue.FromBytes(bytes);
            var json = flx.ToJson;
            Assert.AreEqual(flx.AsVector.Length, 3);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
            
            Assert.AreEqual(flx[1][0].AsString, "1");
            Assert.AreEqual(flx[1][1].AsString, "2");
            Assert.AreEqual(flx[1][2].AsString, "3");
            
            Assert.AreEqual(flx[2][0].AsString, "ds\nkfsdh");
            Assert.AreEqual(flx[2][1].AsString, "sdfsdf");
            Assert.AreEqual(flx[2][2].AsString, "sdfsf");
        }
        
        [Test]
        public void MultipleLineWithSpecialSeparatorAndDoubleQuotesEscapingLineBreak()
        {
            var bytes = CsvToFlexBufferConverter.Convert(
                @"A;B;C
1;2;3
""ds
kfsdh"";sdfsdf;sdfsf
", ';');
            var flx = FlxValue.FromBytes(bytes);
            var json = flx.ToJson;
            Assert.AreEqual(flx.AsVector.Length, 3);
            Assert.AreEqual(flx[0].AsVector.Length, 3);
            Assert.AreEqual(flx[0][0].AsString, "A");
            Assert.AreEqual(flx[0][1].AsString, "B");
            Assert.AreEqual(flx[0][2].AsString, "C");
            
            Assert.AreEqual(flx[1][0].AsString, "1");
            Assert.AreEqual(flx[1][1].AsString, "2");
            Assert.AreEqual(flx[1][2].AsString, "3");
            
            Assert.AreEqual(flx[2][0].AsString, "ds\nkfsdh");
            Assert.AreEqual(flx[2][1].AsString, "sdfsdf");
            Assert.AreEqual(flx[2][2].AsString, "sdfsf");
        }
    }
}

<|start_filename|>FlexBuffersCSharpTests/BitWidthTests.cs<|end_filename|>
using FlexBuffers;
using NUnit.Framework;

namespace FlexBuffersCSharpTests
{
    [TestFixture]
    public class BitWidthTests
    {
        [Test]
        public void Zero()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width(0));
        }
        
        [Test]
        public void One()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width(1));
        }
        
        [Test]
        public void MinusOne()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width(-1));
        }
        
        [Test]
        public void ZeroPointFiveAsDouble()
        {
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width(0.5));
        }
        
        [Test]
        public void ZeroPointOne()
        {
            Assert.AreEqual(BitWidth.Width64, BitWidthUtil.Width(0.1));
        }
        
        [Test]
        public void ZeroPointOneAsFloat()
        {
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width(0.1f));
        }
        
        [Test]
        public void ByteMaxAndMin()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width(byte.MaxValue));
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width(byte.MinValue));
        }
        
        [Test]
        public void ShortMaxAndMin()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((short)sbyte.MaxValue));
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((short)sbyte.MinValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((short)byte.MaxValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((short)short.MaxValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((short)short.MinValue));
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((ushort)byte.MaxValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((ushort)ushort.MaxValue));
        }
        
        [Test]
        public void IntMaxAndMin()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((int)sbyte.MaxValue));
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((int)sbyte.MinValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((int)byte.MaxValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((int)short.MaxValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((int)short.MinValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((int)ushort.MaxValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((int)int.MaxValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((int)int.MinValue));
        }
        
        [Test]
        public void UIntMaxAndMin()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((uint)byte.MaxValue));
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((uint)byte.MinValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((uint)ushort.MaxValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((uint)uint.MaxValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((uint)int.MaxValue));
        }
        
        [Test]
        public void LongMaxAndMin()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((long)sbyte.MaxValue));
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((long)sbyte.MinValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((long)byte.MaxValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((long)short.MaxValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((long)short.MinValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((long)ushort.MaxValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((long)int.MaxValue));
            Assert.AreEqual(BitWidth.Width64, BitWidthUtil.Width((long)uint.MaxValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((long)int.MinValue));
            Assert.AreEqual(BitWidth.Width64, BitWidthUtil.Width((long)long.MaxValue));
            Assert.AreEqual(BitWidth.Width64, BitWidthUtil.Width((long)long.MinValue));
        }
        
        [Test]
        public void ULongMaxAndMin()
        {
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((ulong)byte.MaxValue));
            Assert.AreEqual(BitWidth.Width8, BitWidthUtil.Width((ulong)byte.MinValue));
            Assert.AreEqual(BitWidth.Width16, BitWidthUtil.Width((ulong)ushort.MaxValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((ulong)uint.MaxValue));
            Assert.AreEqual(BitWidth.Width32, BitWidthUtil.Width((ulong)int.MaxValue));
            Assert.AreEqual(BitWidth.Width64, BitWidthUtil.Width((ulong)ulong.MaxValue));
        }

        [Test]
        public void PaddingSize()
        {
            Assert.AreEqual(0, BitWidthUtil.PaddingSize(0, 1));
            Assert.AreEqual(0, BitWidthUtil.PaddingSize(7, 1));
            Assert.AreEqual(1, BitWidthUtil.PaddingSize(7, 2));
            Assert.AreEqual(1, BitWidthUtil.PaddingSize(7, 4));
            Assert.AreEqual(3, BitWidthUtil.PaddingSize(5, 4));
            Assert.AreEqual(7, BitWidthUtil.PaddingSize(1, 8));
        }
    }
}

<|start_filename|>FlexBuffersCSharpTests/FlexBufferTests.cs<|end_filename|>
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using FlexBuffers;
using NUnit.Framework;

namespace FlexBuffersCSharpTests
{
    [TestFixture]
    public class FlexBufferTests
    {
        [Test]
        public void Null()
        {
            Check(new byte[]{0, 0, 1}, FlexBuffer.Null());
        }
        
        [Test]
        public void Bool()
        {
            Check(new byte[]{1, 104, 1}, FlexBuffer.SingleValue(true));
            Check(new byte[]{0, 104, 1}, FlexBuffer.SingleValue(false));
        }
        
        [Test]
        public void OneByte()
        {
            Check(new byte[]{25, 4, 1}, FlexBuffer.SingleValue(25));
            Check(new byte[]{231, 4, 1}, FlexBuffer.SingleValue(-25));
            Check(new byte[]{230, 8, 1}, FlexBuffer.SingleValue(230UL));
        }
        
        [Test]
        public void TwoBytes()
        {
            Check(new byte[]{230, 0, 5, 2}, FlexBuffer.SingleValue(230));
            Check(new byte[]{1, 4, 5, 2}, FlexBuffer.SingleValue(1025));
            Check(new byte[]{255, 251, 5, 2}, FlexBuffer.SingleValue(-1025));
            Check(new byte[]{1, 4, 9, 2}, FlexBuffer.SingleValue(1025UL));
        }
        
        [Test]
        public void FourBytes()
        {
            Check(new byte[]{255, 255, 255, 127, 6, 4}, FlexBuffer.SingleValue(int.MaxValue));
            Check(new byte[]{0, 0, 0, 128, 6, 4}, FlexBuffer.SingleValue(int.MinValue));
            Check(new byte[]{0, 0, 144, 64, 14, 4}, FlexBuffer.SingleValue(4.5));
            Check(new byte[]{205, 204, 204, 61, 14, 4}, FlexBuffer.SingleValue(0.1f));
        }
        
        [Test]
        public void EightBytes()
        {
            Check(new byte[]{255, 255, 255, 255, 0, 0, 0, 0, 7, 8}, FlexBuffer.SingleValue(uint.MaxValue));
            Check(new byte[]{255, 255, 255, 255, 255, 255, 255, 127, 7, 8}, FlexBuffer.SingleValue(long.MaxValue));
            Check(new byte[]{0, 0, 0, 0, 0, 0, 0, 128, 7, 8}, FlexBuffer.SingleValue(long.MinValue));
            Check(new byte[]{255, 255, 255, 255, 255, 255, 255, 255, 11, 8}, FlexBuffer.SingleValue(ulong.MaxValue));
            Check(new byte[]{154, 153, 153, 153, 153, 153, 185, 63, 15, 8}, FlexBuffer.SingleValue(0.1));
        }
        
        [Test]
        public void String()
        {
            Check(new byte[]{5, 77, 97, 120, 105, 109, 0, 6, 20, 1}, FlexBuffer.SingleValue("Maxim"));
            Check(new byte[]{10, 104, 101, 108, 108, 111, 32, 240, 159, 152, 177, 0, 11, 20, 1}, FlexBuffer.SingleValue("hello 😱"));
        }
        
        [Test]
        public void IntVector()
        {
            Check(new byte[]{3, 1, 2, 3, 3, 44, 1}, FlexBuffer.From(new []{1, 2, 3}));
            Check(new byte[]{3, 255, 2, 3, 3, 44, 1}, FlexBuffer.From(new []{-1, 2, 3}));
            Check(new byte[]{3, 0, 1, 0, 43, 2, 3, 0, 6, 45, 1}, FlexBuffer.From(new []{1,555,3}));
            Check(new byte[]{3, 0, 0, 0, 1, 0, 0, 0, 204, 216, 0, 0, 3, 0, 0, 0, 12, 46, 1}, FlexBuffer.From(new []{1,55500,3}));
            Check(new byte[]{3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 172, 128, 94, 239, 12, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 24, 47, 1}, FlexBuffer.From(new []{1, 55555555500, 3}));
        }
        
        [Test]
        public void DoubleVector()
        {
            Check(new byte[]{3, 0, 0, 0, 0, 0, 192, 63, 0, 0, 32, 64, 0, 0, 96, 64, 12, 54, 1}, FlexBuffer.From(new []{1.5, 2.5, 3.5}));
            Check(new byte[]{3, 0, 0, 0, 0, 0, 0, 0, 154, 153, 153, 153, 153, 153, 241, 63, 154, 153, 153, 153, 153, 153, 1, 64, 102, 102, 102, 102, 102, 102, 10, 64, 24, 55, 1}, FlexBuffer.From(new []{1.1, 2.2, 3.3}));
        }
        
        [Test]
        public void BoolVector()
        {
            Check(new byte[]{3, 1, 0, 1, 3, 144, 1}, FlexBuffer.From(new []{true, false, true}));
        }
        
        [Test]
        public void StringVector()
        {
            Check(new byte[]{3, 102, 111, 111, 0, 3, 98, 97, 114, 0, 3, 98, 97, 122, 0, 3, 15, 11, 7, 3, 60, 1}, FlexBuffer.From(new []{"foo", "bar", "baz"}));
        }
        
        [Test]
        public void StringVectorWithRepeatingStrings()
        {
            Check(new byte[]{3, 102, 111, 111, 0, 3, 98, 97, 114, 0, 3, 98, 97, 122, 0, 6, 15, 11, 7, 18, 14, 10, 6, 60, 1}, FlexBuffer.From(new []{"foo", "bar", "baz", "foo", "bar", "baz"}));
        }
        
        [Test]
        public void MixedVector()
        {
            Check(new byte[]
            {
                    3, 102, 111, 111, 0, 0, 0, 0,
                    5, 0, 0, 0, 0, 0, 0, 0, 
                    15, 0, 0, 0, 0, 0, 0, 0, 
                    1, 0, 0, 0, 0, 0, 0, 0, 
                    251, 255, 255, 255, 255, 255, 255, 255, 
                    205, 204, 204, 204, 204, 204, 244, 63, 
                    1, 0, 0, 0, 0, 0, 0, 0, 
                    20, 4, 4, 15, 104, 45, 43, 1
            }, FlexBuffer.From(new List<object>{"foo", 1, -5, 1.3, true}));
        }

        [Test]
        public void StringIntDictSingleValue()
        {
            var dict = new Dictionary<string, int>()
            {
                {"a", 12}
            };
            Check(
                new byte[]{97, 0, 1, 3, 1, 1, 1, 12, 4, 2, 36, 1}, 
                FlexBuffer.From(dict));
        }
        
        [Test]
        public void StringIntDict()
        {
            var dict = new Dictionary<string, int>()
            {
                {"", 45},
                {"a", 12}
            };
            Check(
                new byte[]{0, 97, 0, 2, 4, 4, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1}, 
                FlexBuffer.From(dict));
        }
        
        [Test]
        public void VectorOfSameKeyDicts()
        {
            var dict = new List<Dictionary<string, int>>()
            {
                new Dictionary<string, int>()
                {
                    {"something", 12}
                },
                new Dictionary<string, int>()
                {
                    {"something", 45}
                }
            };
            Check(
                new byte[]
                {
                    115, 111, 109, 101, 116, 104, 105, 110, 103, 0, 
                    1, 11, 1, 1, 1, 12, 4, 6, 1, 1, 45, 4, 2, 8, 4, 36, 36, 4, 40, 1
                }, 
                FlexBuffer.From(dict));
        }
        
        [Test]
        public void MixedVectorWithVectorAndInt()
        {
            var value = new List<object>()
            {
                new []{61},
                64
            };
            // Swift has {1, 61, 4, 2, 3, 64, 40, 4, 4, 40, 1} but it is also untyped
            Check(
                new byte[]{1, 61, 2, 2, 64, 44, 4, 4, 40, 1}, 
                FlexBuffer.From(value));
        }
        
        [Test]
        public void ComplexMap()
        {
            var value = new Dictionary<string, dynamic>()
            {
                {"age", 35},
                {"flags", new bool[]{true, false, true, true}},
                {"weight", 72.5},
                {"name", "Maxim"},
                {"address", new Dictionary<string, dynamic>()
                {
                    {"city", "Bla"},
                    {"zip", "12345"},
                    {"countryCode", "XX"},
                }}, 
            };
            // Different in Swift
            Check(
                new byte[]
                {
                    97, 100, 100, 114, 101, 115, 115, 0, 
                    99, 105, 116, 121, 0, 3, 66, 108, 97, 0, 
                    99, 111, 117, 110, 116, 114, 121, 67, 111, 100, 101, 0, 
                    2, 88, 88, 0, 
                    122, 105, 112, 0, 
                    5, 49, 50, 51, 52, 53, 0, 
                    3, 38, 29, 14, 3, 1, 3, 38, 22, 15, 20, 20, 20, 
                    97, 103, 101, 0, 
                    102, 108, 97, 103, 115, 0, 
                    4, 1, 0, 1, 1, 
                    110, 97, 109, 101, 0, 
                    5, 77, 97, 120, 105, 109, 0, 
                    119, 101, 105, 103, 104, 116, 0, 
                    5, 93, 36, 33, 23, 12, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 0, 51, 0, 0, 0, 45, 0, 0, 0, 0, 0, 145, 66, 36, 4, 144, 20, 14, 25, 38, 1
                }, 
                FlexBuffer.From(value));
        }
        
        [Test]
        public void Long2()
        {
            Check(
                new byte[]{1, 2, 2, 64, 1}, 
                FlexBuffer.SingleValue(1,2));
            Check(
                new byte[]{255, 255, 0, 1, 4, 65, 1}, 
                FlexBuffer.SingleValue(-1,256));
            Check(
                new byte[]{211, 255, 255, 255, 0, 232, 3, 0, 8, 66, 1}, 
                FlexBuffer.SingleValue(-45,256000));
            Check(
                new byte[]{211, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 16, 67, 1}, 
                FlexBuffer.SingleValue(-45,long.MaxValue));
        }
        
        [Test]
        public void ULong2()
        {
            Check(
                new byte[]{1, 2, 2, 68, 1}, 
                FlexBuffer.SingleValue(1UL,2));
            Check(
                new byte[]{1, 0, 0, 1, 4, 69, 1}, 
                FlexBuffer.SingleValue(1UL,256));
            Check(
                new byte[]{45, 0, 0, 0, 0, 232, 3, 0, 8, 70, 1}, 
                FlexBuffer.SingleValue(45UL,256000));
            Check(
                new byte[]{45, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 16, 71, 1}, 
                FlexBuffer.SingleValue(45,ulong.MaxValue));
        }
        
        [Test]
        public void Double2()
        {
            Check(
                new byte[]{205, 204, 140, 63, 0, 0, 0, 192, 8, 74, 1}, 
                FlexBuffer.SingleValue(1.1f, -2));
            Check(
                new byte[]{154, 153, 153, 153, 153, 153, 241, 63, 0, 0, 0, 0, 0, 0, 112, 192, 16, 75, 1}, 
                FlexBuffer.SingleValue(1.1,-256));
        }
        
        [Test]
        public void Long3()
        {
            Check(
                new byte[]{1, 2, 4, 3, 76, 1}, 
                FlexBuffer.SingleValue(1, 2, 4));
            Check(
                new byte[]{255, 255, 0, 1, 4, 0, 6, 77, 1}, 
                FlexBuffer.SingleValue(-1,256, 4));
            Check(
                new byte[]
                {
                    211, 255, 255, 255, 
                    0, 232, 3, 0, 
                    4, 0, 0, 0, 
                    12, 78, 1
                }, 
                FlexBuffer.SingleValue(-45,256000, 4));
            Check(
                new byte[]
                {
                    211, 255, 255, 255, 255, 255, 255, 255, 
                    255, 255, 255, 255, 255, 255, 255, 127, 
                    4, 0, 0, 0, 0, 0, 0, 0, 
                    24, 79, 1
                }, 
                FlexBuffer.SingleValue(-45,long.MaxValue, 4));
        }
        
        [Test]
        public void Long4()
        {
            Check(
                new byte[]{1, 2, 4, 9, 4, 88, 1}, 
                FlexBuffer.SingleValue(1, 2, 4, 9));
            Check(
                new byte[]{255, 255, 0, 1, 4, 0, 9, 0, 8, 89, 1}, 
                FlexBuffer.SingleValue(-1,256, 4, 9));
            Check(
                new byte[]
                {
                    211, 255, 255, 255, 
                    0, 232, 3, 0, 
                    4, 0, 0, 0, 
                    9, 0, 0, 0, 
                    16, 90, 1
                }, 
                FlexBuffer.SingleValue(-45,256000, 4, 9));
            Check(
                new byte[]
                {
                    211, 255, 255, 255, 255, 255, 255, 255, 
                    255, 255, 255, 255, 255, 255, 255, 127, 
                    4, 0, 0, 0, 0, 0, 0, 0, 
                    9, 0, 0, 0, 0, 0, 0, 0, 
                    32, 91, 1
                }, 
                FlexBuffer.SingleValue(-45,long.MaxValue, 4, 9));
        }
        
        [Test]
        public void ULong3()
        {
            Check(
                new byte[]{1, 2, 4, 3, 80, 1}, 
                FlexBuffer.SingleValue(1UL, 2, 4));
            Check(
                new byte[]{1, 0, 0, 1, 4, 0, 6, 81, 1}, 
                FlexBuffer.SingleValue(1UL,256, 4));
            Check(
                new byte[]
                {
                    45, 0, 0, 0, 
                    0, 232, 3, 0, 
                    4, 0, 0, 0, 
                    12, 82, 1
                }, 
                FlexBuffer.SingleValue(45UL,256000, 4));
            Check(
                new byte[]
                {
                    45, 0, 0, 0, 0, 0, 0, 0, 
                    255, 255, 255, 255, 255, 255, 255, 127, 
                    4, 0, 0, 0, 0, 0, 0, 0, 
                    24, 83, 1
                }, 
                FlexBuffer.SingleValue(45UL,long.MaxValue, 4));
        }
        
        [Test]
        public void ULong4()
        {
            Check(
                new byte[]{1, 2, 4, 9, 4, 92, 1}, 
                FlexBuffer.SingleValue(1UL, 2, 4, 9));
            Check(
                new byte[]{1, 0, 0, 1, 4, 0, 9, 0, 8, 93, 1}, 
                FlexBuffer.SingleValue(1UL,256, 4, 9));
            Check(
                new byte[]
                {
                    45, 0, 0, 0, 
                    0, 232, 3, 0, 
                    4, 0, 0, 0, 
                    9, 0, 0, 0, 
                    16, 94, 1
                }, 
                FlexBuffer.SingleValue(45UL,256000, 4, 9));
            Check(
                new byte[]
                {
                    45, 0, 0, 0, 0, 0, 0, 0, 
                    255, 255, 255, 255, 255, 255, 255, 127, 
                    4, 0, 0, 0, 0, 0, 0, 0, 
                    9, 0, 0, 0, 0, 0, 0, 0, 
                    32, 95, 1
                }, 
                FlexBuffer.SingleValue(45UL,long.MaxValue, 4, 9));
        }
        
        [Test]
        public void Double3()
        {
            Check(
                new byte[]
                {
                    205, 204, 140, 63, 
                    0, 0, 0, 64, 
                    0, 0, 128, 64, 
                    12, 86, 1
                }, 
                FlexBuffer.SingleValue(1.1f, 2, 4));
            Check(
                new byte[]
                {
                    154, 153, 153, 153, 153, 153, 241, 63, 
                    0, 0, 0, 0, 0, 0, 112, 64, 
                    0, 0, 0, 0, 0, 0, 16, 64, 
                    24, 87, 1
                }, 
                FlexBuffer.SingleValue(1.1,256, 4));
        }
        
        [Test]
        public void Double4()
        {
            Check(
                new byte[]
                {
                    205, 204, 140, 63, 
                    0, 0, 0, 64, 
                    0, 0, 128, 64, 
                    0, 0, 16, 65, 
                    16, 98, 1
                }, 
                FlexBuffer.SingleValue(1.1f, 2, 4, 9));
            Check(
                new byte[]
                {
                    154, 153, 153, 153, 153, 153, 241, 63, 
                    0, 0, 0, 0, 0, 0, 112, 64, 
                    0, 0, 0, 0, 0, 0, 16, 64, 
                    0, 0, 0, 0, 0, 0, 34, 64, 
                    32, 99, 1
                }, 
                FlexBuffer.SingleValue(1.1,256, 4, 9));
        }
        
        [Test]
        public void Blob()
        {
            Check(
                new byte[]
                {
                    3, 1, 2, 3, 3, 100, 1
                }, 
                FlexBuffer.SingleValue(new byte[]{1, 2, 3}));
            
            var buffer = new byte[1001];
            for (int i = 0; i <= 1000; i++)
            {
                buffer[i] = 5;
            }

            var expected = new byte[1008];
            expected[0] = 233;
            expected[1] = 3;
            Buffer.BlockCopy(buffer, 0, expected, 2, 1000);
            expected[1002] = 5;
            expected[1003] = 0;
            expected[1004] = 234;
            expected[1005] = 3;
            expected[1006] = 101;
            expected[1007] = 2;
            Check(
                expected, 
                FlexBuffer.SingleValue(buffer));
        }

        [Test]
        public void LongStringArray()
        {
            var s1 = new StringBuilder();
            for (int i = 0; i < 260; i++)
            {
                s1.Append("a");
            }
            var s2 = new StringBuilder();
            for (int i = 0; i < 260000; i++)
            {
                s2.Append("b");
            }

            var list = new List<string>(2) {s1.ToString(), s2.ToString()};

            var bytes = FlexBuffer.From(list);

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(2, flx.AsVector.Length);
            Assert.AreEqual(s1.ToString(), flx[0].AsString);
            Assert.AreEqual(s2.ToString(), flx[1].AsString);
            
        }
        
        [Test]
        public void BiggerStringArray()
        {
            var list = new List<string>();
            for (var i = 0; i < 2600; i++)
            {
                list.Add("abc");
            }
            
            var bytes = FlexBuffer.From(list);

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(2600, flx.AsVector.Length);
            for (var i = 0; i < 2600; i++)
            {
                Assert.AreEqual("abc", flx[i].AsString);
            }
        }
        
        [Test]
        public void BiggerBoolArray()
        {
            var list = new List<bool>();
            for (var i = 0; i < 2600; i++)
            {
                list.Add(i%3 == 0);
            }
            
            var bytes = FlexBuffer.From(list);

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(2600, flx.AsVector.Length);
            for (var i = 0; i < 2600; i++)
            {
                Assert.AreEqual(list[i], flx[i].AsBool);
            }
        }
        
        [Test]
        public void BiggerDictionary()
        {
            var dict = new Dictionary<string, int>();
            for (var i = 0; i < 2600; i++)
            {
                dict[i.ToString()] = i;
            }
            
            var bytes = FlexBuffer.From(dict);

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(2600, flx.AsMap.Length);
            for (var i = 0; i < 2600; i++)
            {
                Assert.AreEqual(i, flx[i.ToString()].AsLong);
            }
        }

        private void Check(byte[] expected, byte[] actual)
        {
            Assert.AreEqual(expected, actual, string.Join(", ", actual));
        }
    }
}

<|start_filename|>FlexBuffers/Types.cs<|end_filename|>
using System;

namespace FlexBuffers
{
    public enum Type: byte
    {
        Null, Int, Uint, Float,
        Key, String, IndirectInt, IndirectUInt, IndirectFloat,
        Map, Vector, VectorInt, VectorUInt, VectorFloat, VectorKey, VectorString,
        VectorInt2, VectorUInt2, VectorFloat2,
        VectorInt3, VectorUInt3, VectorFloat3,
        VectorInt4, VectorUInt4, VectorFloat4,
        Blob, Bool, VectorBool = 36
    }

    public static class TypesUtil
    {
        public static bool IsInline(Type type)
        {
            return type == Type.Bool || (byte) type <= (byte) Type.Float;
        }

        public static bool IsTypedVectorElement(Type type)
        {
            var typeValue = (byte) type;
            return type == Type.Bool || (typeValue >= (byte) Type.Int && typeValue <= (byte) Type.String);
        }
        
        public static bool IsTypedVector(Type type)
        {
            var typeValue = (byte) type;
            return type == Type.VectorBool || (typeValue >= (byte) Type.VectorInt && typeValue <= (byte) Type.VectorString);
        }
        
        public static bool IsFixedTypedVector(Type type)
        {
            var typeValue = (byte) type;
            return (typeValue >= (byte) Type.VectorInt2 && typeValue <= (byte) Type.VectorFloat4);
        }

        public static bool IsAVector(Type type)
        {
            return IsTypedVector(type) || IsFixedTypedVector(type) || type == Type.Vector;
        }

        public static Type ToTypedVector(Type type, byte length)
        {
            var typeValue = (byte) type;
            if (length == 0)
            {
                return (Type) (typeValue - (byte) Type.Int + (byte) Type.VectorInt);
            }
            if (length == 2)
            {
                return (Type) (typeValue - (byte) Type.Int + (byte) Type.VectorInt2);
            }
            if (length == 3)
            {
                return (Type) (typeValue - (byte) Type.Int + (byte) Type.VectorInt3);
            }
            if (length == 4)
            {
                return (Type) (typeValue - (byte) Type.Int + (byte) Type.VectorInt4);
            }
            throw new Exception($"Unexpected length: {length}");
        }

        public static Type TypedVectorElementType(Type type)
        {
            var typeValue = (byte) type;
            return (Type) (typeValue - (byte) Type.VectorInt + (byte) Type.Int);
        }

        public static Type FixedTypedVectorElementType(Type type)
        {
            var fixedType = (byte) type - (byte) Type.VectorInt2;
            return (Type)(fixedType % 3 + (int) Type.Int);
        }
        
        public static int FixedTypedVectorElementSize(Type type)
        {
            var fixedType = (byte) type - (byte) Type.VectorInt2;
            return fixedType / 3 + 2;
        }

        public static byte PackedType(Type type, BitWidth bitWidth)
        {
            return (byte) ((byte) bitWidth | ((byte)type << 2));
        }

        public static byte NullPackedType()
        {
            return PackedType(Type.Null, BitWidth.Width8);
        }
    }
}

<|start_filename|>FlexBuffers/XmlToFlexBufferConverter.cs<|end_filename|>
using System.IO;
using System.Xml;

namespace FlexBuffers
{
    public static class XmlToFlexBufferConverter
    {
        public static byte[] Convert(string xmlData)
        {
            XmlDocument doc = new XmlDocument();
            
            doc.Load(new StringReader(xmlData));

            var flx = new FlexBuffer();
            
            Process(flx, doc.DocumentElement);
            
            return flx.Finish();
        }

        private static void Process(FlexBuffer flx, XmlNode element)
        {
            var node = flx.StartVector();
            flx.AddKey("tagName");
            flx.Add(element.Name);
            var attributes = element.Attributes;
            if (attributes != null)
            {
                for (var i = 0; i < attributes.Count; i++)
                {
                    var att = attributes.Item(i);
                    flx.AddKey(att.Name);
                    flx.Add(att.Value);
                }
            }

            var children = element.ChildNodes;
            if (children.Count > 0)
            {
                flx.AddKey("children");
                var childVector = flx.StartVector();
                for (var i = 0; i < children.Count; i++)
                {
                    var child = children[i];
                    if (child.NodeType == XmlNodeType.Text || child.NodeType == XmlNodeType.CDATA)
                    {
                        flx.Add(child.Value);
                    } else if (child.NodeType == XmlNodeType.Comment)
                    {
                        
                    } else
                    {
                        Process(flx, child);    
                    }
                }

                flx.EndVector(childVector, false, false);
            }
            flx.SortAndEndMap(node);
        }
    }
}

<|start_filename|>FlexBuffers/TextScanner.cs<|end_filename|>
using System;
using System.IO;

namespace FlexBuffers
{
    internal struct TextPosition
    {
        public long column;
        public long line;
        public override string ToString()
        {
            return $"line: {line} column: {column}";
        }
    }
	
    internal sealed class TextScanner
    {
        private readonly TextReader _reader;
        private TextPosition _position;

        public TextPosition Position => _position;

        public bool CanRead => (_reader.Peek() != -1);

        internal TextScanner(TextReader reader)
        {
            _reader = reader ?? throw new ArgumentNullException(nameof(reader));
        }

        internal char Peek()
        {
            var next = _reader.Peek();

            if (next == -1)
            {
                throw new Exception($"Incomplete message {_position}");
            }

            return (char)next;
        }

        internal char Read()
        {
            var next = _reader.Read();

            if (next == -1)
            {
                throw new Exception($"Incomplete message {_position}");
            }

            switch (next)
            {
                case '\r':
                    // Normalize '\r\n' line encoding to '\n'.
                    if (_reader.Peek() == '\n')
                    {
                        _reader.Read();
                    }
                    goto case '\n';

                case '\n':
                    _position.line += 1;
                    _position.column = 0;
                    return '\n';

                default:
                    _position.column += 1;
                    return (char)next;
            }
        }

        internal void SkipWhitespace()
        {
            while (char.IsWhiteSpace(Peek()))
            {
                Read();
            }
        }

        internal void Assert(char next)
        {
            if (Peek() == next)
            {
                Read();
            }
            else
            {
                throw new Exception($"Parser expected {next} at position {_position}");
            }
        }

        public void Assert(string next)
        {
            for (var i = 0; i < next.Length; i += 1)
            {
                Assert(next[i]);
            }
        }
    }
}

<|start_filename|>FlexBuffersCSharpTests/XmlToFlexBufferConverterTests.cs<|end_filename|>
using FlexBuffers;
using NUnit.Framework;

namespace FlexBuffersCSharpTests
{
    [TestFixture]
    public class XmlToFlexBufferConverterTests
    {
        [Test]
        public void SingleTagWithAttributes()
        {
            var bytes = XmlToFlexBufferConverter.Convert("<tag1 a=\"123\" b=\"321\"/>");

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(3, flx.AsMap.Length);
            Assert.AreEqual("tag1", flx["tagName"].AsString);
            Assert.AreEqual("123", flx["a"].AsString);
            Assert.AreEqual("321", flx["b"].AsString);
        }
        
        [Test]
        public void SingleOpenCloseTagWithAttributes()
        {
            var bytes = XmlToFlexBufferConverter.Convert("<tag1 a=\"123\" b=\"321\"></tag1>");

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(3, flx.AsMap.Length);
            Assert.AreEqual("tag1", flx["tagName"].AsString);
            Assert.AreEqual("123", flx["a"].AsString);
            Assert.AreEqual("321", flx["b"].AsString);
        }
        
        [Test]
        public void SingleOpenCloseTagWithAttributesAndText()
        {
            var bytes = XmlToFlexBufferConverter.Convert("<tag1 a=\"123\" b=\"321\">hello</tag1>");

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(4, flx.AsMap.Length);
            Assert.AreEqual("tag1", flx["tagName"].AsString);
            Assert.AreEqual("123", flx["a"].AsString);
            Assert.AreEqual("321", flx["b"].AsString);
            
            Assert.AreEqual(1, flx["children"].AsVector.Length);
            Assert.AreEqual("hello", flx["children"][0].AsString);
        }
        
        [Test]
        public void SingleOpenCloseTagWithAttributesAndTextSplitByTag()
        {
            var bytes = XmlToFlexBufferConverter.Convert("<tag1 a=\"123\" b=\"321\">hello <br/> Maxim</tag1>");

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(4, flx.AsMap.Length);
            Assert.AreEqual("tag1", flx["tagName"].AsString);
            Assert.AreEqual("123", flx["a"].AsString);
            Assert.AreEqual("321", flx["b"].AsString);
            
            Assert.AreEqual(3, flx["children"].AsVector.Length);
            Assert.AreEqual("hello ", flx["children"][0].AsString);
            Assert.AreEqual(1, flx["children"][1].AsMap.Length);
            Assert.AreEqual("br", flx["children"][1]["tagName"].AsString);
            Assert.AreEqual(" Maxim", flx["children"][2].AsString);
        }
        
        [Test]
        public void ComplexXml()
        {
            var xml = @"<?xml version=""1.0""?>
<!-- This is a sample XML document -->
<!DOCTYPE Items [<!ENTITY number ""123"">]>
<Items>
<Item>Test with an entity: &number;</Item>
<Item>Test with a child element <more/> stuff</Item>
<Item>Test with a CDATA section <![CDATA[<456>]]> def</Item>
<Item>Test with a char entity: &#65;</Item>
<!-- Fourteen chars in this element.-->
<Item>1234567890ABCD</Item>
</Items>
";
            var bytes = XmlToFlexBufferConverter.Convert(xml);

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(2, flx.AsMap.Length);
            Assert.AreEqual("Items", flx["tagName"].AsString);
            Assert.AreEqual(5, flx["children"].AsVector.Length);
            
            Assert.AreEqual(2, flx["children"][0].AsMap.Length);
            Assert.AreEqual("Item", flx["children"][0]["tagName"].AsString);
            Assert.AreEqual(2, flx["children"][0]["children"].AsVector.Length);
            Assert.AreEqual("Test with an entity: ", flx["children"][0]["children"][0].AsString);
            Assert.AreEqual(2, flx["children"][0]["children"][1].AsMap.Length);
            Assert.AreEqual("number", flx["children"][0]["children"][1]["tagName"].AsString);
            Assert.AreEqual(1, flx["children"][0]["children"][1]["children"].AsVector.Length);
            Assert.AreEqual("123", flx["children"][0]["children"][1]["children"][0].AsString);
            
            Assert.AreEqual("Item", flx["children"][1]["tagName"].AsString);
            Assert.AreEqual(3, flx["children"][1]["children"].AsVector.Length);
            Assert.AreEqual("Test with a child element ", flx["children"][1]["children"][0].AsString);
            Assert.AreEqual(1, flx["children"][1]["children"][1].AsMap.Length);
            Assert.AreEqual("more", flx["children"][1]["children"][1]["tagName"].AsString);
            Assert.AreEqual(" stuff", flx["children"][1]["children"][2].AsString);
            
            Assert.AreEqual("Item", flx["children"][2]["tagName"].AsString);
            Assert.AreEqual(3, flx["children"][2]["children"].AsVector.Length);
            Assert.AreEqual("Test with a CDATA section ", flx["children"][2]["children"][0].AsString);
            Assert.AreEqual("<456>", flx["children"][2]["children"][1].AsString);
            Assert.AreEqual(" def", flx["children"][2]["children"][2].AsString);
            
            Assert.AreEqual("Item", flx["children"][3]["tagName"].AsString);
            Assert.AreEqual(1, flx["children"][3]["children"].AsVector.Length);
            Assert.AreEqual("Test with a char entity: A", flx["children"][3]["children"][0].AsString);
            
            Assert.AreEqual("Item", flx["children"][4]["tagName"].AsString);
            Assert.AreEqual(1, flx["children"][4]["children"].AsVector.Length);
            Assert.AreEqual("1234567890ABCD", flx["children"][4]["children"][0].AsString);
        }
    }
}

<|start_filename|>FlexBuffersCSharpTests/FlexBufferBuilderTests.cs<|end_filename|>
using FlexBuffers;
using NUnit.Framework;

namespace FlexBuffersCSharpTests
{
    [TestFixture]
    public class FlexBufferBuilderTests
    {
        [Test]
        public void SmallIntVector()
        {
            var bytes = FlexBufferBuilder.Vector(builder =>
            {
                builder.Add(1);
                builder.Add(2);
                builder.Add(3);
                builder.Add(4);
                builder.Add(5);
            });

            var flx = FlxValue.FromBytes(bytes);
            Assert.AreEqual(5, flx.AsVector.Length);
            Assert.AreEqual(1, flx[0].AsLong);
            Assert.AreEqual(2, flx[1].AsLong);
            Assert.AreEqual(3, flx[2].AsLong);
            Assert.AreEqual(4, flx[3].AsLong);
            Assert.AreEqual(5, flx[4].AsLong);
        }
        
        [Test]
        public void SmallIntVectorAndNestedVector()
        {
            var bytes = FlexBufferBuilder.Vector(v1 =>
            {
                v1.Add(1);
                v1.Add(2);
                v1.Add(3);
                v1.Add(4);
                v1.Add(5);
                v1.Vector(v2 => {
                    v2.Add("hello");
                    v2.Add("world");
                });
            });

            var flx = FlxValue.FromBytes(bytes);
            Assert.AreEqual(6, flx.AsVector.Length);
            Assert.AreEqual(1, flx[0].AsLong);
            Assert.AreEqual(2, flx[1].AsLong);
            Assert.AreEqual(3, flx[2].AsLong);
            Assert.AreEqual(4, flx[3].AsLong);
            Assert.AreEqual(5, flx[4].AsLong);
            Assert.AreEqual(2, flx[5].AsVector.Length);
            Assert.AreEqual("hello", flx[5][0].AsString);
            Assert.AreEqual("world", flx[5][1].AsString);
        }
        
        [Test]
        public void SmallMap()
        {
            var bytes = FlexBufferBuilder.Map(builder =>
            {
                builder.Add("name", "Maxim");
                builder.Add("age", 38);
                builder.Add("weight", 72.5);
            });

            var flx = FlxValue.FromBytes(bytes);
            Assert.AreEqual(3, flx.AsMap.Length);
            Assert.AreEqual(38, flx["age"].AsLong);
            Assert.AreEqual(72.5, flx["weight"].AsDouble);
            Assert.AreEqual("Maxim", flx["name"].AsString);
        }
        
        [Test]
        public void ComplexMap()
        {
            var bytes = FlexBufferBuilder.Map(root =>
            {
                root.Add("name", "Maxim");
                root.Add("age", 38);
                root.Add("weight", 72.5);
                root.Map("address", address =>
                {
                    address.Add("city", "Bla");
                    address.Add("zip", "12345");
                    address.Add("countryCode", "XX");
                });
                root.Vector("flags", tags =>
                {
                    tags.Add(true);
                    tags.Add(false);
                    tags.Add(true);
                    tags.Add(true);
                });
            });

            var flx = FlxValue.FromBytes(bytes);
            Assert.AreEqual(5, flx.AsMap.Length);
            
            Assert.AreEqual(38, flx["age"].AsLong);
            Assert.AreEqual(72.5, flx["weight"].AsDouble);
            Assert.AreEqual("Maxim", flx["name"].AsString);
            
            Assert.AreEqual(4, flx["flags"].AsVector.Length);
            Assert.AreEqual(true, flx["flags"][0].AsBool);
            Assert.AreEqual(false, flx["flags"][1].AsBool);
            Assert.AreEqual(true, flx["flags"][2].AsBool);
            Assert.AreEqual(true, flx["flags"][3].AsBool);
            
            Assert.AreEqual(3, flx["address"].AsMap.Length);
            Assert.AreEqual("Bla", flx["address"]["city"].AsString);
            Assert.AreEqual("12345", flx["address"]["zip"].AsString);
            Assert.AreEqual("XX", flx["address"]["countryCode"].AsString);
        }

        [Test]
        public void FixVectors()
        {
            var bytes = FlexBufferBuilder.Map(root =>
            {
                root.Add("a", 1, 2);
                root.Add("b", 1, 2, 3);
                root.Add("c", 1, 2, 3, 4);
                root.Add("d", 1UL, 2);
                root.Add("e", 1UL, 2, 3);
                root.Add("f", 1UL, 2, 3, 4);
                root.Add("g", 1.1, 2);
                root.Add("h", 1.1, 2, 3);
                root.Add("i", 1.1, 2, 3, 4);
                root.Vector("j", vec =>
                {
                    vec.Add(1, 2);
                    vec.Add(1, 2, 3);
                    vec.Add(1, 2, 3, 4);
                    vec.Add(1UL, 2);
                    vec.Add(1UL, 2, 3);
                    vec.Add(1UL, 2, 3, 4);
                    vec.Add(1.1, 2);
                    vec.Add(1.1, 2, 3);
                    vec.Add(1.1, 2, 3, 4);
                });
            });

            var flx = FlxValue.FromBytes(bytes);
            Assert.AreEqual(10, flx.AsMap.Length);
            Assert.AreEqual(1, flx["a"][0].AsLong);
            Assert.AreEqual(2, flx["a"][1].AsLong);
            Assert.AreEqual(1, flx["b"][0].AsLong);
            Assert.AreEqual(2, flx["b"][1].AsLong);
            Assert.AreEqual(3, flx["b"][2].AsLong);
            Assert.AreEqual(1, flx["c"][0].AsLong);
            Assert.AreEqual(2, flx["c"][1].AsLong);
            Assert.AreEqual(3, flx["c"][2].AsLong);
            Assert.AreEqual(4, flx["c"][3].AsLong);
            Assert.AreEqual(1, flx["d"][0].AsULong);
            Assert.AreEqual(2, flx["d"][1].AsULong);
            Assert.AreEqual(1, flx["e"][0].AsULong);
            Assert.AreEqual(2, flx["e"][1].AsULong);
            Assert.AreEqual(3, flx["e"][2].AsULong);
            Assert.AreEqual(1, flx["f"][0].AsULong);
            Assert.AreEqual(2, flx["f"][1].AsULong);
            Assert.AreEqual(3, flx["f"][2].AsULong);
            Assert.AreEqual(4, flx["f"][3].AsULong);
            Assert.AreEqual(1.1, flx["g"][0].AsDouble);
            Assert.AreEqual(2, flx["g"][1].AsDouble);
            Assert.AreEqual(1.1, flx["h"][0].AsDouble);
            Assert.AreEqual(2, flx["h"][1].AsDouble);
            Assert.AreEqual(3, flx["h"][2].AsDouble);
            Assert.AreEqual(1.1, flx["i"][0].AsDouble);
            Assert.AreEqual(2, flx["i"][1].AsDouble);
            Assert.AreEqual(3, flx["i"][2].AsDouble);
            Assert.AreEqual(4, flx["i"][3].AsDouble);

            var v = flx["j"].AsVector;
            Assert.AreEqual(9, v.Length);
            Assert.AreEqual(1, v[0][0].AsLong);
            Assert.AreEqual(2, v[0][1].AsLong);
            Assert.AreEqual(1, v[1][0].AsLong);
            Assert.AreEqual(2, v[1][1].AsLong);
            Assert.AreEqual(3, v[1][2].AsLong);
            Assert.AreEqual(1, v[2][0].AsLong);
            Assert.AreEqual(2, v[2][1].AsLong);
            Assert.AreEqual(3, v[2][2].AsLong);
            Assert.AreEqual(4, v[2][3].AsLong);
            Assert.AreEqual(1, v[3][0].AsULong);
            Assert.AreEqual(2, v[3][1].AsULong);
            Assert.AreEqual(1, v[4][0].AsULong);
            Assert.AreEqual(2, v[4][1].AsULong);
            Assert.AreEqual(3, v[4][2].AsULong);
            Assert.AreEqual(1, v[5][0].AsULong);
            Assert.AreEqual(2, v[5][1].AsULong);
            Assert.AreEqual(3, v[5][2].AsULong);
            Assert.AreEqual(4, v[5][3].AsULong);
            Assert.AreEqual(1.1, v[6][0].AsDouble);
            Assert.AreEqual(2, v[6][1].AsDouble);
            Assert.AreEqual(1.1, v[7][0].AsDouble);
            Assert.AreEqual(2, v[7][1].AsDouble);
            Assert.AreEqual(3, v[7][2].AsDouble);
            Assert.AreEqual(1.1, v[8][0].AsDouble);
            Assert.AreEqual(2, v[8][1].AsDouble);
            Assert.AreEqual(3, v[8][2].AsDouble);
            Assert.AreEqual(4, v[8][3].AsDouble);
        }

        [Test]
        public void IndirectValuesInMap()
        {
            var bytes = FlexBufferBuilder.Map(root =>
            {
                root.Add("a", -123, true);
                root.Add("b", 123UL, true);
                root.Add("c", 123.3, true);
            });

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(3, flx.AsMap.Length);
            Assert.AreEqual(-123, flx["a"].AsLong);
            Assert.AreEqual(123, flx["b"].AsULong);
            Assert.AreEqual(123.3, flx["c"].AsDouble);
        }
        
        [Test]
        public void IndirectValuesInMapToJson()
        {
            var bytes = FlexBufferBuilder.Map(root =>
            {
                root.Add("a", -123, true);
                root.Add("b", 123UL, true);
                root.Add("c", 123.3, true);
            });

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(
                "{\"a\":-123,\"b\":123,\"c\":123.3}", 
                flx.ToJson);
        }
        
        [Test]
        public void IndirectValuesInVector()
        {
            var bytes = FlexBufferBuilder.Vector(root =>
            {
                root.Add(-123, true);
                root.Add(123UL, true);
                root.Add(123.3, true);
            });

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(3, flx.AsVector.Length);
            Assert.AreEqual(-123, flx[0].AsLong);
            Assert.AreEqual(123, flx[1].AsULong);
            Assert.AreEqual(123.3, flx[2].AsDouble);
        }
        
        [Test]
        public void IndirectValuesInVectorToJson()
        {
            var bytes = FlexBufferBuilder.Vector(root =>
            {
                root.Add(-123, true);
                root.Add(123UL, true);
                root.Add(123.3, true);
            });

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(
                "[-123,123,123.3]", 
                flx.ToJson);
        }
        
        [Test]
        public void AddNullAndBlobToNestedToJson()
        {
            var bytes = FlexBufferBuilder.Vector(root =>
            {
                root.AddNull();
                root.Add(new byte[]{1,2,3});
                root.Map(map =>
                {
                    map.AddNull("a");
                    map.Add("b", new byte[]{3,4,5});
                });
            });

            var flx = FlxValue.FromBytes(bytes);
            
            Assert.AreEqual(
                "[null,\"AQID\",{\"a\":null,\"b\":\"AwQF\"}]", 
                flx.ToJson);
        }
    }
}