diff --git a/csharp/sbe-dll/DirectBuffer.cs b/csharp/sbe-dll/DirectBuffer.cs
index 52b78ea4af..09eb64ec7e 100644
--- a/csharp/sbe-dll/DirectBuffer.cs
+++ b/csharp/sbe-dll/DirectBuffer.cs
@@ -64,6 +64,25 @@ public DirectBuffer(byte* pBuffer, int bufferLength, BufferOverflowDelegate buff
Wrap(pBuffer, bufferLength);
}
+ ///
+ /// Attach a view to a buffer owned by external code
+ ///
+ /// byte buffer
+ public DirectBuffer(ArraySegment buffer) : this(buffer, null)
+ {
+ }
+
+ ///
+ /// Attach a view to a buffer owned by external code
+ ///
+ /// byte buffer
+ /// delegate to allow reallocation of buffer
+ public DirectBuffer(ArraySegment buffer, BufferOverflowDelegate bufferOverflow)
+ {
+ this.bufferOverflow = bufferOverflow;
+ Wrap(buffer);
+ }
+
///
/// Creates a DirectBuffer that can later be wrapped
///
@@ -114,6 +133,24 @@ public void Wrap(byte* pBuffer, int bufferLength)
_needToFreeGCHandle = false;
}
+ ///
+ /// Recycles an existing from a byte buffer owned by external code
+ ///
+ /// buffer of bytes
+ public void Wrap(ArraySegment buffer)
+ {
+ if (buffer == null) throw new ArgumentNullException(nameof(buffer));
+
+ FreeGCHandle();
+
+ // pin the buffer so it does not get moved around by GC, this is required since we use pointers
+ _pinnedGCHandle = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned);
+ _needToFreeGCHandle = true;
+
+ _pBuffer = ((byte*)_pinnedGCHandle.AddrOfPinnedObject().ToPointer()) + buffer.Offset;
+ _capacity = buffer.Count;
+ }
+
///
/// Capacity of the underlying buffer
///
diff --git a/csharp/sbe-tests/DirectBufferTests.cs b/csharp/sbe-tests/DirectBufferTests.cs
index 2ac82e4e07..4c37ebe1f0 100644
--- a/csharp/sbe-tests/DirectBufferTests.cs
+++ b/csharp/sbe-tests/DirectBufferTests.cs
@@ -66,6 +66,40 @@ public void ConstructFromNativeBuffer()
}
}
+ [TestMethod]
+ public void ConstructFromByteArray()
+ {
+ var buffer = new byte[16];
+
+ const int value = 5;
+ const int index = 0;
+
+ using (var directBuffer = new DirectBuffer(buffer))
+ {
+ directBuffer.Int64PutLittleEndian(index, value);
+ Assert.AreEqual(value, buffer[index]);
+ }
+ }
+
+ [TestMethod]
+ public void ConstructFromArraySegment()
+ {
+ const int value = 5;
+ const int index = 0;
+ const int offset = 512;
+ const int size = 1024;
+
+ var bigBuffer = new byte[size];
+ var buffer = new ArraySegment(bigBuffer, offset, size - offset);
+
+ using (var directBuffer = new DirectBuffer(buffer))
+ {
+ directBuffer.Int64PutLittleEndian(index, value);
+ Assert.AreEqual(value, bigBuffer[offset + index]);
+ Assert.AreEqual(value, buffer.AsSpan()[index]);
+ }
+ }
+
[TestMethod]
public void Recycle()
{