Skip to content

Commit afb62b5

Browse files
authored
DirectBuffer - Support ArraySegment for underlying array (#878)
* DirectBuffer - Support ArraySegment for backing storage * fix comments
1 parent 57979f8 commit afb62b5

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

csharp/sbe-dll/DirectBuffer.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,25 @@ public DirectBuffer(byte* pBuffer, int bufferLength, BufferOverflowDelegate buff
6464
Wrap(pBuffer, bufferLength);
6565
}
6666

67+
/// <summary>
68+
/// Attach a view to a buffer owned by external code
69+
/// </summary>
70+
/// <param name="buffer">byte buffer</param>
71+
public DirectBuffer(ArraySegment<byte> buffer) : this(buffer, null)
72+
{
73+
}
74+
75+
/// <summary>
76+
/// Attach a view to a buffer owned by external code
77+
/// </summary>
78+
/// <param name="buffer">byte buffer</param>
79+
/// <param name="bufferOverflow">delegate to allow reallocation of buffer</param>
80+
public DirectBuffer(ArraySegment<byte> buffer, BufferOverflowDelegate bufferOverflow)
81+
{
82+
this.bufferOverflow = bufferOverflow;
83+
Wrap(buffer);
84+
}
85+
6786
/// <summary>
6887
/// Creates a DirectBuffer that can later be wrapped
6988
/// </summary>
@@ -114,6 +133,24 @@ public void Wrap(byte* pBuffer, int bufferLength)
114133
_needToFreeGCHandle = false;
115134
}
116135

136+
/// <summary>
137+
/// Recycles an existing <see cref="DirectBuffer"/> from a byte buffer owned by external code
138+
/// </summary>
139+
/// <param name="buffer">buffer of bytes</param>
140+
public void Wrap(ArraySegment<byte> buffer)
141+
{
142+
if (buffer == null) throw new ArgumentNullException(nameof(buffer));
143+
144+
FreeGCHandle();
145+
146+
// pin the buffer so it does not get moved around by GC, this is required since we use pointers
147+
_pinnedGCHandle = GCHandle.Alloc(buffer.Array, GCHandleType.Pinned);
148+
_needToFreeGCHandle = true;
149+
150+
_pBuffer = ((byte*)_pinnedGCHandle.AddrOfPinnedObject().ToPointer()) + buffer.Offset;
151+
_capacity = buffer.Count;
152+
}
153+
117154
/// <summary>
118155
/// Capacity of the underlying buffer
119156
/// </summary>

csharp/sbe-tests/DirectBufferTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,40 @@ public void ConstructFromNativeBuffer()
6666
}
6767
}
6868

69+
[TestMethod]
70+
public void ConstructFromByteArray()
71+
{
72+
var buffer = new byte[16];
73+
74+
const int value = 5;
75+
const int index = 0;
76+
77+
using (var directBuffer = new DirectBuffer(buffer))
78+
{
79+
directBuffer.Int64PutLittleEndian(index, value);
80+
Assert.AreEqual(value, buffer[index]);
81+
}
82+
}
83+
84+
[TestMethod]
85+
public void ConstructFromArraySegment()
86+
{
87+
const int value = 5;
88+
const int index = 0;
89+
const int offset = 512;
90+
const int size = 1024;
91+
92+
var bigBuffer = new byte[size];
93+
var buffer = new ArraySegment<byte>(bigBuffer, offset, size - offset);
94+
95+
using (var directBuffer = new DirectBuffer(buffer))
96+
{
97+
directBuffer.Int64PutLittleEndian(index, value);
98+
Assert.AreEqual(value, bigBuffer[offset + index]);
99+
Assert.AreEqual(value, buffer.AsSpan<byte>()[index]);
100+
}
101+
}
102+
69103
[TestMethod]
70104
public void Recycle()
71105
{

0 commit comments

Comments
 (0)