diff --git a/net/FlatBuffers/ByteBuffer.cs b/net/FlatBuffers/ByteBuffer.cs
new file mode 100644
index 0000000..5e212dd
--- /dev/null
+++ b/net/FlatBuffers/ByteBuffer.cs
@@ -0,0 +1,891 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// There are 3 #defines that have an impact on performance / features of this ByteBuffer implementation
+//
+//      UNSAFE_BYTEBUFFER 
+//          This will use unsafe code to manipulate the underlying byte array. This
+//          can yield a reasonable performance increase.
+//
+//      BYTEBUFFER_NO_BOUNDS_CHECK
+//          This will disable the bounds check asserts to the byte array. This can
+//          yield a small performance gain in normal code..
+//
+//      ENABLE_SPAN_T
+//          This will enable reading and writing blocks of memory with a Span<T> instead if just
+//          T[].  You can also enable writing directly to shared memory or other types of memory
+//          by providing a custom implementation of ByteBufferAllocator.
+//          ENABLE_SPAN_T also requires UNSAFE_BYTEBUFFER to be defined
+//
+// Using UNSAFE_BYTEBUFFER and BYTEBUFFER_NO_BOUNDS_CHECK together can yield a
+// performance gain of ~15% for some operations, however doing so is potentially 
+// dangerous. Do so at your own risk!
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+
+#if ENABLE_SPAN_T
+using System.Buffers.Binary;
+#endif
+
+#if ENABLE_SPAN_T && !UNSAFE_BYTEBUFFER
+#error ENABLE_SPAN_T requires UNSAFE_BYTEBUFFER to also be defined
+#endif
+
+namespace FlatBuffers
+{
+    public abstract class ByteBufferAllocator
+    {
+#if ENABLE_SPAN_T
+        public abstract Span<byte> Span { get; }
+        public abstract ReadOnlySpan<byte> ReadOnlySpan { get; }
+        public abstract Memory<byte> Memory { get; }
+        public abstract ReadOnlyMemory<byte> ReadOnlyMemory { get; }
+
+#else
+        public byte[] Buffer
+        {
+            get;
+            protected set;
+        }
+#endif
+
+        public int Length
+        {
+            get;
+            protected set;
+        }
+
+        public abstract void GrowFront(int newSize);
+    }
+
+    public sealed class ByteArrayAllocator : ByteBufferAllocator
+    {
+        private byte[] _buffer;
+
+        public ByteArrayAllocator(byte[] buffer)
+        {
+            _buffer = buffer;
+            InitBuffer();
+        }
+
+        public override void GrowFront(int newSize)
+        {
+            if ((Length & 0xC0000000) != 0)
+                throw new Exception(
+                    "ByteBuffer: cannot grow buffer beyond 2 gigabytes.");
+
+            if (newSize < Length)
+                throw new Exception("ByteBuffer: cannot truncate buffer.");
+
+            byte[] newBuffer = new byte[newSize];
+            System.Buffer.BlockCopy(_buffer, 0, newBuffer, newSize - Length, Length);
+            _buffer = newBuffer;
+            InitBuffer();
+        }
+
+#if ENABLE_SPAN_T
+        public override Span<byte> Span => _buffer;
+        public override ReadOnlySpan<byte> ReadOnlySpan => _buffer;
+        public override Memory<byte> Memory => _buffer;
+        public override ReadOnlyMemory<byte> ReadOnlyMemory => _buffer;
+#endif
+
+        private void InitBuffer()
+        {
+            Length = _buffer.Length;
+#if !ENABLE_SPAN_T
+            Buffer = _buffer;
+#endif
+        }
+    }
+
+    /// <summary>
+    /// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
+    /// </summary>
+    public class ByteBuffer
+    {
+        private ByteBufferAllocator _buffer;
+        private int _pos;  // Must track start of the buffer.
+
+        public ByteBuffer(ByteBufferAllocator allocator, int position)
+        {
+            _buffer = allocator;
+            _pos = position;
+        }
+
+        public ByteBuffer(int size) : this(new byte[size]) { }
+
+        public ByteBuffer(byte[] buffer) : this(buffer, 0) { }
+
+        public ByteBuffer(byte[] buffer, int pos)
+        {
+            _buffer = new ByteArrayAllocator(buffer);
+            _pos = pos;
+        }
+
+        public int Position
+        {
+            get { return _pos; }
+            set { _pos = value; }
+        }
+
+        public int Length { get { return _buffer.Length; } }
+
+        public void Reset()
+        {
+            _pos = 0;
+        }
+
+        // Create a new ByteBuffer on the same underlying data.
+        // The new ByteBuffer's position will be same as this buffer's.
+        public ByteBuffer Duplicate()
+        {
+            return new ByteBuffer(_buffer, Position);
+        }
+
+        // Increases the size of the ByteBuffer, and copies the old data towards
+        // the end of the new buffer.
+        public void GrowFront(int newSize)
+        {
+            _buffer.GrowFront(newSize);
+        }
+
+        public byte[] ToArray(int pos, int len)
+        {
+            return ToArray<byte>(pos, len);
+        }
+
+        /// <summary>
+        /// A lookup of type sizes. Used instead of Marshal.SizeOf() which has additional
+        /// overhead, but also is compatible with generic functions for simplified code.
+        /// </summary>
+        private static Dictionary<Type, int> genericSizes = new Dictionary<Type, int>()
+        {
+            { typeof(bool),     sizeof(bool) },
+            { typeof(float),    sizeof(float) },
+            { typeof(double),   sizeof(double) },
+            { typeof(sbyte),    sizeof(sbyte) },
+            { typeof(byte),     sizeof(byte) },
+            { typeof(short),    sizeof(short) },
+            { typeof(ushort),   sizeof(ushort) },
+            { typeof(int),      sizeof(int) },
+            { typeof(uint),     sizeof(uint) },
+            { typeof(ulong),    sizeof(ulong) },
+            { typeof(long),     sizeof(long) },
+        };
+
+        /// <summary>
+        /// Get the wire-size (in bytes) of a type supported by flatbuffers.
+        /// </summary>
+        /// <param name="t">The type to get the wire size of</param>
+        /// <returns></returns>
+        public static int SizeOf<T>()
+        {
+            return genericSizes[typeof(T)];
+        }
+
+        /// <summary>
+        /// Checks if the Type provided is supported as scalar value
+        /// </summary>
+        /// <typeparam name="T">The Type to check</typeparam>
+        /// <returns>True if the type is a scalar type that is supported, falsed otherwise</returns>
+        public static bool IsSupportedType<T>()
+        {
+            return genericSizes.ContainsKey(typeof(T));
+        }
+
+        /// <summary>
+        /// Get the wire-size (in bytes) of an typed array
+        /// </summary>
+        /// <typeparam name="T">The type of the array</typeparam>
+        /// <param name="x">The array to get the size of</param>
+        /// <returns>The number of bytes the array takes on wire</returns>
+        public static int ArraySize<T>(T[] x)
+        {
+            return SizeOf<T>() * x.Length;
+        }
+
+#if ENABLE_SPAN_T
+        public static int ArraySize<T>(Span<T> x)
+        {
+            return SizeOf<T>() * x.Length;
+        }
+#endif
+
+        // Get a portion of the buffer casted into an array of type T, given
+        // the buffer position and length.
+#if ENABLE_SPAN_T
+        public T[] ToArray<T>(int pos, int len)
+            where T : struct
+        {
+            AssertOffsetAndLength(pos, len);
+            return MemoryMarshal.Cast<byte, T>(_buffer.ReadOnlySpan.Slice(pos)).Slice(0, len).ToArray();
+        }
+#else
+        public T[] ToArray<T>(int pos, int len)
+            where T : struct
+        {
+            AssertOffsetAndLength(pos, len);
+            T[] arr = new T[len];
+            Buffer.BlockCopy(_buffer.Buffer, pos, arr, 0, ArraySize(arr));
+            return arr;
+        }
+#endif
+
+        public byte[] ToSizedArray()
+        {
+            return ToArray<byte>(Position, Length - Position);
+        }
+
+        public byte[] ToFullArray()
+        {
+            return ToArray<byte>(0, Length);
+        }
+
+#if ENABLE_SPAN_T
+        public ReadOnlyMemory<byte> ToReadOnlyMemory(int pos, int len)
+        {
+            return _buffer.ReadOnlyMemory.Slice(pos, len);
+        }
+
+        public Memory<byte> ToMemory(int pos, int len)
+        {
+            return _buffer.Memory.Slice(pos, len);
+        }
+
+        public Span<byte> ToSpan(int pos, int len)
+        {
+            return _buffer.Span.Slice(pos, len);
+        }
+#else
+        public ArraySegment<byte> ToArraySegment(int pos, int len)
+        {
+            return new ArraySegment<byte>(_buffer.Buffer, pos, len);
+        }
+
+        public MemoryStream ToMemoryStream(int pos, int len)
+        {
+            return new MemoryStream(_buffer.Buffer, pos, len);
+        }
+#endif
+
+#if !UNSAFE_BYTEBUFFER
+        // Pre-allocated helper arrays for convertion.
+        private float[] floathelper = new[] { 0.0f };
+        private int[] inthelper = new[] { 0 };
+        private double[] doublehelper = new[] { 0.0 };
+        private ulong[] ulonghelper = new[] { 0UL };
+#endif // !UNSAFE_BYTEBUFFER
+
+        // Helper functions for the unsafe version.
+        static public ushort ReverseBytes(ushort input)
+        {
+            return (ushort)(((input & 0x00FFU) << 8) |
+                            ((input & 0xFF00U) >> 8));
+        }
+        static public uint ReverseBytes(uint input)
+        {
+            return ((input & 0x000000FFU) << 24) |
+                   ((input & 0x0000FF00U) <<  8) |
+                   ((input & 0x00FF0000U) >>  8) |
+                   ((input & 0xFF000000U) >> 24);
+        }
+        static public ulong ReverseBytes(ulong input)
+        {
+            return (((input & 0x00000000000000FFUL) << 56) |
+                    ((input & 0x000000000000FF00UL) << 40) |
+                    ((input & 0x0000000000FF0000UL) << 24) |
+                    ((input & 0x00000000FF000000UL) <<  8) |
+                    ((input & 0x000000FF00000000UL) >>  8) |
+                    ((input & 0x0000FF0000000000UL) >> 24) |
+                    ((input & 0x00FF000000000000UL) >> 40) |
+                    ((input & 0xFF00000000000000UL) >> 56));
+        }
+
+#if !UNSAFE_BYTEBUFFER
+        // Helper functions for the safe (but slower) version.
+        protected void WriteLittleEndian(int offset, int count, ulong data)
+        {
+            if (BitConverter.IsLittleEndian)
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    _buffer.Buffer[offset + i] = (byte)(data >> i * 8);
+                }
+            }
+            else
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    _buffer.Buffer[offset + count - 1 - i] = (byte)(data >> i * 8);
+                }
+            }
+        }
+
+        protected ulong ReadLittleEndian(int offset, int count)
+        {
+            AssertOffsetAndLength(offset, count);
+            ulong r = 0;
+            if (BitConverter.IsLittleEndian)
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    r |= (ulong)_buffer.Buffer[offset + i] << i * 8;
+                }
+            }
+            else
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    r |= (ulong)_buffer.Buffer[offset + count - 1 - i] << i * 8;
+                }
+            }
+            return r;
+        }
+#endif // !UNSAFE_BYTEBUFFER
+
+        private void AssertOffsetAndLength(int offset, int length)
+        {
+#if !BYTEBUFFER_NO_BOUNDS_CHECK
+            if (offset < 0 ||
+                offset > _buffer.Length - length)
+                throw new ArgumentOutOfRangeException();
+#endif
+        }
+
+#if ENABLE_SPAN_T
+
+        public void PutSbyte(int offset, sbyte value)
+        {
+            AssertOffsetAndLength(offset, sizeof(sbyte));
+            _buffer.Span[offset] = (byte)value;
+        }
+
+        public void PutByte(int offset, byte value)
+        {
+            AssertOffsetAndLength(offset, sizeof(byte));
+            _buffer.Span[offset] = value;
+        }
+
+        public void PutByte(int offset, byte value, int count)
+        {
+            AssertOffsetAndLength(offset, sizeof(byte) * count);
+            Span<byte> span = _buffer.Span.Slice(offset, count);
+            for (var i = 0; i < span.Length; ++i)
+                span[i] = value;
+        }
+#else
+        public void PutSbyte(int offset, sbyte value)
+        {
+            AssertOffsetAndLength(offset, sizeof(sbyte));
+            _buffer.Buffer[offset] = (byte)value;
+        }
+
+        public void PutByte(int offset, byte value)
+        {
+            AssertOffsetAndLength(offset, sizeof(byte));
+            _buffer.Buffer[offset] = value;
+        }
+
+        public void PutByte(int offset, byte value, int count)
+        {
+            AssertOffsetAndLength(offset, sizeof(byte) * count);
+            for (var i = 0; i < count; ++i)
+                _buffer.Buffer[offset + i] = value;
+        }
+#endif
+
+        // this method exists in order to conform with Java ByteBuffer standards
+        public void Put(int offset, byte value)
+        {
+            PutByte(offset, value);
+        }
+
+#if ENABLE_SPAN_T
+        public unsafe void PutStringUTF8(int offset, string value)
+        {
+            AssertOffsetAndLength(offset, value.Length);
+            fixed (char* s = value)
+            {
+                fixed (byte* buffer = &MemoryMarshal.GetReference(_buffer.Span))
+                {
+                    Encoding.UTF8.GetBytes(s, value.Length, buffer + offset, Length - offset);
+                }
+            }
+        }
+#else
+        public void PutStringUTF8(int offset, string value)
+        {
+            AssertOffsetAndLength(offset, value.Length);
+            Encoding.UTF8.GetBytes(value, 0, value.Length,
+                _buffer.Buffer, offset);
+        }
+#endif
+
+#if UNSAFE_BYTEBUFFER
+        // Unsafe but more efficient versions of Put*.
+        public void PutShort(int offset, short value)
+        {
+            PutUshort(offset, (ushort)value);
+        }
+
+        public unsafe void PutUshort(int offset, ushort value)
+        {
+            AssertOffsetAndLength(offset, sizeof(ushort));
+#if ENABLE_SPAN_T
+            Span<byte> span = _buffer.Span.Slice(offset);
+            BinaryPrimitives.WriteUInt16LittleEndian(span, value);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                *(ushort*)(ptr + offset) = BitConverter.IsLittleEndian
+                    ? value
+                    : ReverseBytes(value);
+            }
+#endif
+        }
+
+        public void PutInt(int offset, int value)
+        {
+            PutUint(offset, (uint)value);
+        }
+
+        public unsafe void PutUint(int offset, uint value)
+        {
+            AssertOffsetAndLength(offset, sizeof(uint));
+#if ENABLE_SPAN_T
+            Span<byte> span = _buffer.Span.Slice(offset);
+            BinaryPrimitives.WriteUInt32LittleEndian(span, value);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                *(uint*)(ptr + offset) = BitConverter.IsLittleEndian
+                    ? value
+                    : ReverseBytes(value);
+            }
+#endif
+        }
+
+        public unsafe void PutLong(int offset, long value)
+        {
+            PutUlong(offset, (ulong)value);
+        }
+
+        public unsafe void PutUlong(int offset, ulong value)
+        {
+            AssertOffsetAndLength(offset, sizeof(ulong));
+#if ENABLE_SPAN_T
+            Span<byte> span = _buffer.Span.Slice(offset);
+            BinaryPrimitives.WriteUInt64LittleEndian(span, value);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                *(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
+                    ? value
+                    : ReverseBytes(value);
+            }
+#endif
+        }
+
+        public unsafe void PutFloat(int offset, float value)
+        {
+            AssertOffsetAndLength(offset, sizeof(float));
+#if ENABLE_SPAN_T
+            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span))
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+#endif
+            {
+                if (BitConverter.IsLittleEndian)
+                {
+                    *(float*)(ptr + offset) = value;
+                }
+                else
+                {
+                    *(uint*)(ptr + offset) = ReverseBytes(*(uint*)(&value));
+                }
+            }
+        }
+
+        public unsafe void PutDouble(int offset, double value)
+        {
+            AssertOffsetAndLength(offset, sizeof(double));
+#if ENABLE_SPAN_T
+            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.Span))
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+#endif
+            {
+                if (BitConverter.IsLittleEndian)
+                {
+                    *(double*)(ptr + offset) = value;
+                }
+                else
+                {
+                    *(ulong*)(ptr + offset) = ReverseBytes(*(ulong*)(&value));
+                }
+            }
+        }
+#else // !UNSAFE_BYTEBUFFER
+        // Slower versions of Put* for when unsafe code is not allowed.
+        public void PutShort(int offset, short value)
+        {
+            AssertOffsetAndLength(offset, sizeof(short));
+            WriteLittleEndian(offset, sizeof(short), (ulong)value);
+        }
+
+        public void PutUshort(int offset, ushort value)
+        {
+            AssertOffsetAndLength(offset, sizeof(ushort));
+            WriteLittleEndian(offset, sizeof(ushort), (ulong)value);
+        }
+
+        public void PutInt(int offset, int value)
+        {
+            AssertOffsetAndLength(offset, sizeof(int));
+            WriteLittleEndian(offset, sizeof(int), (ulong)value);
+        }
+
+        public void PutUint(int offset, uint value)
+        {
+            AssertOffsetAndLength(offset, sizeof(uint));
+            WriteLittleEndian(offset, sizeof(uint), (ulong)value);
+        }
+
+        public void PutLong(int offset, long value)
+        {
+            AssertOffsetAndLength(offset, sizeof(long));
+            WriteLittleEndian(offset, sizeof(long), (ulong)value);
+        }
+
+        public void PutUlong(int offset, ulong value)
+        {
+            AssertOffsetAndLength(offset, sizeof(ulong));
+            WriteLittleEndian(offset, sizeof(ulong), value);
+        }
+
+        public void PutFloat(int offset, float value)
+        {
+            AssertOffsetAndLength(offset, sizeof(float));
+            floathelper[0] = value;
+            Buffer.BlockCopy(floathelper, 0, inthelper, 0, sizeof(float));
+            WriteLittleEndian(offset, sizeof(float), (ulong)inthelper[0]);
+        }
+
+        public void PutDouble(int offset, double value)
+        {
+            AssertOffsetAndLength(offset, sizeof(double));
+            doublehelper[0] = value;
+            Buffer.BlockCopy(doublehelper, 0, ulonghelper, 0, sizeof(double));
+            WriteLittleEndian(offset, sizeof(double), ulonghelper[0]);
+        }
+
+#endif // UNSAFE_BYTEBUFFER
+
+#if ENABLE_SPAN_T
+        public sbyte GetSbyte(int index)
+        {
+            AssertOffsetAndLength(index, sizeof(sbyte));
+            return (sbyte)_buffer.ReadOnlySpan[index];
+        }
+
+        public byte Get(int index)
+        {
+            AssertOffsetAndLength(index, sizeof(byte));
+            return _buffer.ReadOnlySpan[index];
+        }
+#else
+        public sbyte GetSbyte(int index)
+        {
+            AssertOffsetAndLength(index, sizeof(sbyte));
+            return (sbyte)_buffer.Buffer[index];
+        }
+
+        public byte Get(int index)
+        {
+            AssertOffsetAndLength(index, sizeof(byte));
+            return _buffer.Buffer[index];
+        }
+#endif
+
+#if ENABLE_SPAN_T
+        public unsafe string GetStringUTF8(int startPos, int len)
+        {
+            fixed (byte* buffer = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan.Slice(startPos)))
+            {
+                return Encoding.UTF8.GetString(buffer, len);
+            }
+        }
+#else
+        public string GetStringUTF8(int startPos, int len)
+        {
+            return Encoding.UTF8.GetString(_buffer.Buffer, startPos, len);
+        }
+#endif
+
+#if UNSAFE_BYTEBUFFER
+        // Unsafe but more efficient versions of Get*.
+        public short GetShort(int offset)
+        {
+            return (short)GetUshort(offset);
+        }
+
+        public unsafe ushort GetUshort(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(ushort));
+#if ENABLE_SPAN_T
+            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
+            return BinaryPrimitives.ReadUInt16LittleEndian(span);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                return BitConverter.IsLittleEndian
+                    ? *(ushort*)(ptr + offset)
+                    : ReverseBytes(*(ushort*)(ptr + offset));
+            }
+#endif
+        }
+
+        public int GetInt(int offset)
+        {
+            return (int)GetUint(offset);
+        }
+
+        public unsafe uint GetUint(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(uint));
+#if ENABLE_SPAN_T
+            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
+            return BinaryPrimitives.ReadUInt32LittleEndian(span);
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                return BitConverter.IsLittleEndian
+                    ? *(uint*)(ptr + offset)
+                    : ReverseBytes(*(uint*)(ptr + offset));
+            }
+#endif
+        }
+
+        public long GetLong(int offset)
+        {
+            return (long)GetUlong(offset);
+        }
+
+        public unsafe ulong GetUlong(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(ulong));
+#if ENABLE_SPAN_T
+            ReadOnlySpan<byte> span = _buffer.ReadOnlySpan.Slice(offset);
+            return BinaryPrimitives.ReadUInt64LittleEndian(span);
+#else            
+            fixed (byte* ptr = _buffer.Buffer)
+            {
+                return BitConverter.IsLittleEndian
+                    ? *(ulong*)(ptr + offset)
+                    : ReverseBytes(*(ulong*)(ptr + offset));
+            }
+#endif
+        }
+
+        public unsafe float GetFloat(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(float));
+#if ENABLE_SPAN_T
+            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan))
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+#endif
+            {
+                if (BitConverter.IsLittleEndian)
+                {
+                    return *(float*)(ptr + offset);
+                }
+                else
+                {
+                    uint uvalue = ReverseBytes(*(uint*)(ptr + offset));
+                    return *(float*)(&uvalue);
+                }
+            }
+        }
+
+        public unsafe double GetDouble(int offset)
+        {
+            AssertOffsetAndLength(offset, sizeof(double));
+#if ENABLE_SPAN_T
+            fixed (byte* ptr = &MemoryMarshal.GetReference(_buffer.ReadOnlySpan))
+#else
+            fixed (byte* ptr = _buffer.Buffer)
+#endif
+            {
+                if (BitConverter.IsLittleEndian)
+                {
+                    return *(double*)(ptr + offset);
+                }
+                else
+                {
+                    ulong uvalue = ReverseBytes(*(ulong*)(ptr + offset));
+                    return *(double*)(&uvalue);
+                }
+            }
+        }
+#else // !UNSAFE_BYTEBUFFER
+        // Slower versions of Get* for when unsafe code is not allowed.
+        public short GetShort(int index)
+        {
+            return (short)ReadLittleEndian(index, sizeof(short));
+        }
+
+        public ushort GetUshort(int index)
+        {
+            return (ushort)ReadLittleEndian(index, sizeof(ushort));
+        }
+
+        public int GetInt(int index)
+        {
+            return (int)ReadLittleEndian(index, sizeof(int));
+        }
+
+        public uint GetUint(int index)
+        {
+            return (uint)ReadLittleEndian(index, sizeof(uint));
+        }
+
+        public long GetLong(int index)
+        {
+            return (long)ReadLittleEndian(index, sizeof(long));
+        }
+
+        public ulong GetUlong(int index)
+        {
+            return ReadLittleEndian(index, sizeof(ulong));
+        }
+
+        public float GetFloat(int index)
+        {
+            int i = (int)ReadLittleEndian(index, sizeof(float));
+            inthelper[0] = i;
+            Buffer.BlockCopy(inthelper, 0, floathelper, 0, sizeof(float));
+            return floathelper[0];
+        }
+
+        public double GetDouble(int index)
+        {
+            ulong i = ReadLittleEndian(index, sizeof(double));
+            // There's Int64BitsToDouble but it uses unsafe code internally.
+            ulonghelper[0] = i;
+            Buffer.BlockCopy(ulonghelper, 0, doublehelper, 0, sizeof(double));
+            return doublehelper[0];
+        }
+#endif // UNSAFE_BYTEBUFFER
+
+        /// <summary>
+        /// Copies an array of type T into this buffer, ending at the given
+        /// offset into this buffer. The starting offset is calculated based on the length
+        /// of the array and is the value returned.
+        /// </summary>
+        /// <typeparam name="T">The type of the input data (must be a struct)</typeparam>
+        /// <param name="offset">The offset into this buffer where the copy will end</param>
+        /// <param name="x">The array to copy data from</param>
+        /// <returns>The 'start' location of this buffer now, after the copy completed</returns>
+        public int Put<T>(int offset, T[] x)
+            where T : struct
+        {
+            if (x == null)
+            {
+                throw new ArgumentNullException("Cannot put a null array");
+            }
+
+            if (x.Length == 0)
+            {
+                throw new ArgumentException("Cannot put an empty array");
+            }
+
+            if (!IsSupportedType<T>())
+            {
+                throw new ArgumentException("Cannot put an array of type "
+                    + typeof(T) + " into this buffer");
+            }
+
+            if (BitConverter.IsLittleEndian)
+            {
+                int numBytes = ByteBuffer.ArraySize(x);
+                offset -= numBytes;
+                AssertOffsetAndLength(offset, numBytes);
+                // if we are LE, just do a block copy
+#if ENABLE_SPAN_T
+                MemoryMarshal.Cast<T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
+#else
+                Buffer.BlockCopy(x, 0, _buffer.Buffer, offset, numBytes);
+#endif
+            }
+            else
+            {
+                throw new NotImplementedException("Big Endian Support not implemented yet " +
+                    "for putting typed arrays");
+                // if we are BE, we have to swap each element by itself
+                //for(int i = x.Length - 1; i >= 0; i--)
+                //{
+                //  todo: low priority, but need to genericize the Put<T>() functions
+                //}
+            }
+            return offset;
+        }
+
+#if ENABLE_SPAN_T
+        public int Put<T>(int offset, Span<T> x)
+            where T : struct
+        {
+            if (x.Length == 0)
+            {
+                throw new ArgumentException("Cannot put an empty array");
+            }
+
+            if (!IsSupportedType<T>())
+            {
+                throw new ArgumentException("Cannot put an array of type "
+                    + typeof(T) + " into this buffer");
+            }
+
+            if (BitConverter.IsLittleEndian)
+            {
+                int numBytes = ByteBuffer.ArraySize(x);
+                offset -= numBytes;
+                AssertOffsetAndLength(offset, numBytes);
+                // if we are LE, just do a block copy
+                MemoryMarshal.Cast<T, byte>(x).CopyTo(_buffer.Span.Slice(offset, numBytes));
+            }
+            else
+            {
+                throw new NotImplementedException("Big Endian Support not implemented yet " +
+                    "for putting typed arrays");
+                // if we are BE, we have to swap each element by itself
+                //for(int i = x.Length - 1; i >= 0; i--)
+                //{
+                //  todo: low priority, but need to genericize the Put<T>() functions
+                //}
+            }
+            return offset;
+        }
+#endif
+    }
+}
