|
15 | 15 | */ |
16 | 16 | namespace HiveMQtt.MQTT5.Packets; |
17 | 17 |
|
| 18 | +using System.Buffers; |
18 | 19 | using System.IO; |
19 | 20 | using System.Text; |
20 | 21 | using HiveMQtt.Client.Options; |
@@ -102,18 +103,37 @@ public byte[] Encode() |
102 | 103 | Array.Clear(passwordString.ToCharArray(), 0, passwordString.Length); |
103 | 104 | } |
104 | 105 |
|
105 | | - // Construct the final packet |
106 | | - var constructedPacket = new MemoryStream((int)vhAndPayloadStream.Length + 5); |
| 106 | + // Calculate the size needed for the final packet |
| 107 | + var vhAndPayloadLength = (int)vhAndPayloadStream.Length; |
| 108 | + var fixedHeaderSize = 1 + GetVariableByteIntegerSize(vhAndPayloadLength); |
| 109 | + var totalSize = fixedHeaderSize + vhAndPayloadLength; |
107 | 110 |
|
108 | | - // Write the Fixed Header |
109 | | - constructedPacket.WriteByte(((byte)ControlPacketType.Connect) << 4); |
110 | | - _ = EncodeVariableByteInteger(constructedPacket, (int)vhAndPayloadStream.Length); |
111 | | - |
112 | | - // Copy the Variable Header and Payload |
113 | | - vhAndPayloadStream.Position = 0; |
114 | | - vhAndPayloadStream.CopyTo(constructedPacket); |
115 | | - |
116 | | - return constructedPacket.ToArray(); |
| 111 | + // Use ArrayPool for the final buffer |
| 112 | + var rentedBuffer = ArrayPool<byte>.Shared.Rent(totalSize); |
| 113 | + try |
| 114 | + { |
| 115 | + var bufferSpan = rentedBuffer.AsSpan(0, totalSize); |
| 116 | + var offset = 0; |
| 117 | + |
| 118 | + // Write the Fixed Header |
| 119 | + bufferSpan[offset++] = ((byte)ControlPacketType.Connect) << 4; |
| 120 | + offset += EncodeVariableByteIntegerToSpan(bufferSpan[offset..], vhAndPayloadLength); |
| 121 | + |
| 122 | + // Copy the Variable Header and Payload directly from the stream |
| 123 | + vhAndPayloadStream.Position = 0; |
| 124 | + var vhAndPayloadBuffer = vhAndPayloadStream.GetBuffer(); |
| 125 | + var vhAndPayloadSpan = new Span<byte>(vhAndPayloadBuffer, 0, vhAndPayloadLength); |
| 126 | + vhAndPayloadSpan.CopyTo(bufferSpan[offset..]); |
| 127 | + |
| 128 | + // Return a properly sized array |
| 129 | + var result = new byte[totalSize]; |
| 130 | + bufferSpan[..totalSize].CopyTo(result); |
| 131 | + return result; |
| 132 | + } |
| 133 | + finally |
| 134 | + { |
| 135 | + ArrayPool<byte>.Shared.Return(rentedBuffer); |
| 136 | + } |
117 | 137 | } |
118 | 138 | } |
119 | 139 |
|
|
0 commit comments