Skip to content

Commit 1ac59f0

Browse files
fix: fastbufferreader does not honor arraysegment configuration (up port) (#3321)
Up port of #3320 This PR resolves the issue where `FastBufferReader` did not provide constructors that would automatically use an `ArraySegment`'s configuration (Count and Offset) to define the `FastBufferReader`. [MTTB-34](https://jira.unity3d.com/browse/MTTB-34) fix: #2885 ## Changelog - Added `FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocator)` constructor that uses the `ArraySegment.Offset` as the `FastBufferReader` offset and the `ArraySegment.Count` as the `FastBufferReader` length. - Added `FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocator, int length = -1)` constructor that uses the `ArraySegment.Offset` as the `FastBufferReader` offset. ## Testing and Documentation - Includes unit test. - Includes public API documentation. <!-- Uncomment and mark items off with a * if this PR deprecates any API: ### Deprecated API - [ ] An `[Obsolete]` attribute was added along with a `(RemovedAfter yyyy-mm-dd)` entry. - [ ] An [api updater] was added. - [ ] Deprecation of the API is explained in the CHANGELOG. - [ ] The users can understand why this API was removed and what they should use instead. -->
1 parent e2ae8eb commit 1ac59f0

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Additional documentation and release notes are available at [Multiplayer Documen
1010

1111
### Added
1212

13+
- Added `FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocator)` constructor that uses the `ArraySegment.Offset` as the `FastBufferReader` offset and the `ArraySegment.Count` as the `FastBufferReader` length. (#3321)
14+
- Added `FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocator, int length = -1)` constructor that uses the `ArraySegment.Offset` as the `FastBufferReader` offset. (#3321)
15+
1316
### Fixed
1417

1518
- Fixed `OnClientConnectedCallback` passing incorrect `clientId` when scene management is disabled. (#3312)

com.unity.netcode.gameobjects/Runtime/Serialization/FastBufferReader.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,54 @@ public unsafe FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocato
140140
}
141141
}
142142

143+
/// <summary>
144+
/// Create a FastBufferReader from an ArraySegment that uses the ArraySegment.Offset for the reader's offset.
145+
///
146+
/// A new buffer will be created using the given allocator and the value will be copied in.
147+
/// FastBufferReader will then own the data.
148+
///
149+
/// Allocator.None is not supported for byte[]. If you need this functionality, use a fixed() block
150+
/// and ensure the FastBufferReader isn't used outside that block.
151+
/// </summary>
152+
/// <param name="buffer">The buffer to copy from</param>
153+
/// <param name="copyAllocator">The allocator type used for internal data when copying an existing buffer if other than Allocator.None is specified, that memory will be owned by this FastBufferReader instance</param>
154+
/// <param name="length">The number of bytes to copy (all if this is -1)</param>
155+
public unsafe FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocator, int length = -1)
156+
{
157+
if (copyAllocator == Allocator.None)
158+
{
159+
throw new NotSupportedException("Allocator.None cannot be used with managed source buffers.");
160+
}
161+
fixed (byte* data = buffer.Array)
162+
{
163+
164+
Handle = CreateHandle(data, length == -1 ? buffer.Count : length, buffer.Offset, copyAllocator, Allocator.Temp);
165+
}
166+
}
167+
168+
/// <summary>
169+
/// Create a FastBufferReader from an ArraySegment that uses the ArraySegment.Offset for the reader's offset and the ArraySegment.Count for the reader's length.
170+
///
171+
/// A new buffer will be created using the given allocator and the value will be copied in.
172+
/// FastBufferReader will then own the data.
173+
///
174+
/// Allocator.None is not supported for byte[]. If you need this functionality, use a fixed() block
175+
/// and ensure the FastBufferReader isn't used outside that block.
176+
/// </summary>
177+
/// <param name="buffer">The buffer to copy from</param>
178+
/// <param name="copyAllocator">The allocator type used for internal data when copying an existing buffer if other than Allocator.None is specified, that memory will be owned by this FastBufferReader instance</param>
179+
public unsafe FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocator)
180+
{
181+
if (copyAllocator == Allocator.None)
182+
{
183+
throw new NotSupportedException("Allocator.None cannot be used with managed source buffers.");
184+
}
185+
fixed (byte* data = buffer.Array)
186+
{
187+
Handle = CreateHandle(data, buffer.Count, buffer.Offset, copyAllocator, Allocator.Temp);
188+
}
189+
}
190+
143191
/// <summary>
144192
/// Create a FastBufferReader from an existing byte array.
145193
///

com.unity.netcode.gameobjects/Tests/Editor/Serialization/FastBufferReaderTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,5 +1579,21 @@ public unsafe void WhenCallingTryBeginReadInternal_AllowedReadPositionDoesNotMov
15791579
Assert.AreEqual(reader.Handle->AllowedReadMark, 25);
15801580
}
15811581
}
1582+
1583+
[Test]
1584+
public unsafe void WhenUsingArraySegment_ConstructorHonorsArraySegmentConfiguration()
1585+
{
1586+
var bytes = new byte[] { 0, 1, 2, 3 };
1587+
var segment = new ArraySegment<byte>(bytes, 1, 3);
1588+
var reader = new FastBufferReader(segment, Allocator.Temp);
1589+
1590+
var readerArray = reader.ToArray();
1591+
Assert.True(readerArray.Length == bytes.Length - 1, $"Array of reader should have a length of {bytes.Length - 1} but was {readerArray.Length}!");
1592+
for (int i = 0; i < readerArray.Length; i++)
1593+
{
1594+
Assert.True(bytes[i + 1] == readerArray[i], $"Value of {nameof(readerArray)} at index {i} is {readerArray[i]} but should be {bytes[i + 1]}!");
1595+
}
1596+
reader.Dispose();
1597+
}
15821598
}
15831599
}

0 commit comments

Comments
 (0)