diff --git a/Assets/Mirror/Core/NetworkWriter.cs b/Assets/Mirror/Core/NetworkWriter.cs index 27d321a31..18bbad616 100644 --- a/Assets/Mirror/Core/NetworkWriter.cs +++ b/Assets/Mirror/Core/NetworkWriter.cs @@ -197,6 +197,26 @@ public void WriteBytes(byte[] array, int offset, int count) Array.ConstrainedCopy(array, offset, this.buffer, Position, count); Position += count; } + // write an unsafe byte* array. + // useful for bit tree compression, etc. + public unsafe bool WriteBytes(byte* ptr, int offset, int size) + { + EnsureCapacity(Position + size); + + fixed (byte* destination = &buffer[Position]) + { + // write 'size' bytes at position + // 10 mio writes: 868ms + // Array.Copy(value.Array, value.Offset, buffer, Position, value.Count); + // 10 mio writes: 775ms + // Buffer.BlockCopy(value.Array, value.Offset, buffer, Position, value.Count); + // 10 mio writes: 637ms + UnsafeUtility.MemCpy(destination, ptr + offset, size); + } + + Position += size; + return true; + } /// Writes any type that mirror supports. Uses weaver populated Writer(T).write. [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Assets/Mirror/Tests/Editor/NetworkWriterTest.cs b/Assets/Mirror/Tests/Editor/NetworkWriterTest.cs index 81d0da9c6..3ed64c736 100644 --- a/Assets/Mirror/Tests/Editor/NetworkWriterTest.cs +++ b/Assets/Mirror/Tests/Editor/NetworkWriterTest.cs @@ -133,6 +133,22 @@ public void TestWritingBytesSegment() Assert.That(deserialized.Array[deserialized.Offset + i], Is.EqualTo(data[i])); } + [Test] + public unsafe void WriteBytes_Ptr() + { + NetworkWriter writer = new NetworkWriter(); + + // make sure this respects position & offset + writer.WriteByte(0xFF); + + byte[] bytes = {0x01, 0x02, 0x03, 0x04}; + fixed (byte* ptr = bytes) + { + Assert.True(writer.WriteBytes(ptr, 1, 2)); + Assert.True(writer.ToArraySegment().SequenceEqual(new byte[] {0xFF, 0x02, 0x03})); + } + } + // write byte[], read segment [Test] public void TestWritingBytesAndReadingSegment()