Skip to content

Commit 66a7be4

Browse files
authoredFeb 25, 2025
fix: fastbufferreader does not honor arraysegment configuration (#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 up-port: #3321 ## 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 94160ec commit 66a7be4

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed
 

‎com.unity.netcode.gameobjects/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Additional documentation and release notes are available at [Multiplayer Documen
99
## [Unreleased]
1010

1111
### Added
12+
- 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. (#3320)
13+
- Added `FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocator, int length = -1)` constructor that uses the `ArraySegment.Offset` as the `FastBufferReader` offset. (#3320)
1214

1315
### Fixed
1416

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

+49
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,59 @@ public unsafe FastBufferReader(ArraySegment<byte> buffer, Allocator copyAllocato
136136
}
137137
fixed (byte* data = buffer.Array)
138138
{
139+
139140
Handle = CreateHandle(data, length == -1 ? buffer.Count : length, offset, copyAllocator, Allocator.Temp);
140141
}
141142
}
142143

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

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

+16
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
}

‎pvpExceptions.json

+1
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@
731731
"Unity.Netcode.EditorTests.FastBufferReaderTests: void WhenCallingTryBeginRead_TheAllowedReadPositionIsMarkedRelativeToCurrentPosition(): undocumented",
732732
"Unity.Netcode.EditorTests.FastBufferReaderTests: void WhenReadingAfterSeeking_TheNewReadComesFromTheCorrectPosition(): undocumented",
733733
"Unity.Netcode.EditorTests.FastBufferReaderTests: void WhenCallingTryBeginReadInternal_AllowedReadPositionDoesNotMoveBackward(): undocumented",
734+
"Unity.Netcode.EditorTests.FastBufferReaderTests: void WhenUsingArraySegment_ConstructorHonorsArraySegmentConfiguration(): undocumented",
734735
"Unity.Netcode.EditorTests.FastBufferWriterTests: undocumented",
735736
"Unity.Netcode.EditorTests.FastBufferWriterTests: void RunTypeTest(T): undocumented",
736737
"Unity.Netcode.EditorTests.FastBufferWriterTests: void RunTypeTestSafe(T): undocumented",

0 commit comments

Comments
 (0)
Failed to load comments.