22// The .NET Foundation licenses this file to you under the MIT license.
33// See the LICENSE file in the project root for more information.
44
5+ using System . Buffers ;
6+ using System . Buffers . Binary ;
57using System . Runtime . CompilerServices ;
68using System . Text ;
79using MQTTnet . Exceptions ;
@@ -108,29 +110,45 @@ public void Write(MqttBufferWriter propertyWriter)
108110 WriteBinary ( propertyWriter . _buffer , 0 , propertyWriter . Length ) ;
109111 }
110112
111- public void WriteBinary ( byte [ ] value )
113+ public void WriteBinary ( ReadOnlySequence < byte > value )
112114 {
113- if ( value == null || value . Length == 0 )
115+ if ( value . IsEmpty )
114116 {
115- EnsureAdditionalCapacity ( 2 ) ;
117+ WriteEmptyBinary ( ) ;
118+ return ;
119+ }
116120
117- _buffer [ _position ] = 0 ;
118- _buffer [ _position + 1 ] = 0 ;
121+ EnsureAdditionalCapacity ( value . Length + 2 ) ;
122+
123+ _buffer [ _position ] = ( byte ) ( value . Length >> 8 ) ;
124+ _buffer [ _position + 1 ] = ( byte ) value . Length ;
119125
120- IncreasePosition ( 2 ) ;
126+ Advance ( 2 ) ;
127+
128+ foreach ( var segment in value )
129+ {
130+ MqttMemoryHelper . Copy ( segment , 0 , _buffer , _position + 2 , segment . Length ) ;
131+ Advance ( segment . Length ) ;
121132 }
122- else
133+ }
134+
135+ public void WriteBinary ( ReadOnlyMemory < byte > value )
136+ {
137+ if ( value . Length == 0 )
123138 {
124- var valueLength = value . Length ;
139+ WriteEmptyBinary ( ) ;
140+ return ;
141+ }
125142
126- EnsureAdditionalCapacity ( valueLength + 2 ) ;
143+ EnsureAdditionalCapacity ( value . Length + 2 ) ;
127144
128- _buffer [ _position ] = ( byte ) ( valueLength >> 8 ) ;
129- _buffer [ _position + 1 ] = ( byte ) valueLength ;
145+ _buffer [ _position ] = ( byte ) ( value . Length >> 8 ) ;
146+ _buffer [ _position + 1 ] = ( byte ) value . Length ;
130147
131- MqttMemoryHelper . Copy ( value , 0 , _buffer , _position + 2 , valueLength ) ;
132- IncreasePosition ( valueLength + 2 ) ;
133- }
148+ Advance ( 2 ) ;
149+
150+ MqttMemoryHelper . Copy ( value , 0 , _buffer , _position + 2 , ( int ) value . Length ) ;
151+ Advance ( value . Length ) ;
134152 }
135153
136154 public void WriteBinary ( byte [ ] buffer , int offset , int count )
@@ -145,15 +163,7 @@ public void WriteBinary(byte[] buffer, int offset, int count)
145163 EnsureAdditionalCapacity ( count ) ;
146164
147165 MqttMemoryHelper . Copy ( buffer , offset , _buffer , _position , count ) ;
148- IncreasePosition ( count ) ;
149- }
150-
151- public void WriteByte ( byte @byte )
152- {
153- EnsureAdditionalCapacity ( 1 ) ;
154-
155- _buffer [ _position ] = @byte ;
156- IncreasePosition ( 1 ) ;
166+ Advance ( count ) ;
157167 }
158168
159169 public void WriteString ( string value )
@@ -165,7 +175,7 @@ public void WriteString(string value)
165175 _buffer [ _position ] = 0 ;
166176 _buffer [ _position + 1 ] = 0 ;
167177
168- IncreasePosition ( 2 ) ;
178+ Advance ( 2 ) ;
169179 }
170180 else
171181 {
@@ -189,34 +199,60 @@ public void WriteString(string value)
189199 _buffer [ _position ] = ( byte ) ( writtenBytes >> 8 ) ;
190200 _buffer [ _position + 1 ] = ( byte ) writtenBytes ;
191201
192- IncreasePosition ( writtenBytes + 2 ) ;
202+ Advance ( writtenBytes + 2 ) ;
193203 }
194204 }
195205
206+ public void WriteByte ( byte @byte )
207+ {
208+ const int size = sizeof ( byte ) ;
209+ var span = GetSpan ( size ) ;
210+
211+ span [ 0 ] = @byte ;
212+ Advance ( size ) ;
213+ }
214+
196215 public void WriteTwoByteInteger ( ushort value )
197216 {
198- EnsureAdditionalCapacity ( 2 ) ;
217+ const int size = sizeof ( ushort ) ;
218+ var span = GetSpan ( size ) ;
219+
220+ BinaryPrimitives . WriteUInt16BigEndian ( span , value ) ;
221+
222+ Advance ( size ) ;
223+ }
224+
225+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
226+ Span < byte > GetSpan ( int size )
227+ {
228+ var freeSpace = _buffer . Length - _position ;
229+ if ( freeSpace < size )
230+ {
231+ EnsureCapacity ( _buffer . Length + size - freeSpace ) ;
232+ }
199233
200- _buffer [ _position ] = ( byte ) ( value >> 8 ) ;
201- IncreasePosition ( 1 ) ;
202- _buffer [ _position ] = ( byte ) value ;
203- IncreasePosition ( 1 ) ;
234+ return _buffer . AsSpan ( _position , size ) ;
204235 }
205236
237+
238+
239+
240+
241+
206242 public void WriteVariableByteInteger ( uint value )
207243 {
208244 if ( value == 0 )
209245 {
210246 _buffer [ _position ] = 0 ;
211- IncreasePosition ( 1 ) ;
247+ Advance ( 1 ) ;
212248
213249 return ;
214250 }
215251
216252 if ( value <= 127 )
217253 {
218254 _buffer [ _position ] = ( byte ) value ;
219- IncreasePosition ( 1 ) ;
255+ Advance ( 1 ) ;
220256
221257 return ;
222258 }
@@ -238,11 +274,11 @@ public void WriteVariableByteInteger(uint value)
238274 size ++ ;
239275 } while ( x > 0 ) ;
240276
241- IncreasePosition ( size ) ;
277+ Advance ( size ) ;
242278 }
243279
244280 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
245- void EnsureAdditionalCapacity ( int additionalCapacity )
281+ void EnsureAdditionalCapacity ( long additionalCapacity )
246282 {
247283 var bufferLength = _buffer . Length ;
248284
@@ -256,7 +292,7 @@ void EnsureAdditionalCapacity(int additionalCapacity)
256292 }
257293
258294 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
259- void EnsureCapacity ( int capacity )
295+ void EnsureCapacity ( long capacity )
260296 {
261297 var newBufferLength = _buffer . Length ;
262298
@@ -275,7 +311,7 @@ void EnsureCapacity(int capacity)
275311 }
276312
277313 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
278- void IncreasePosition ( int length )
314+ void Advance ( int length )
279315 {
280316 _position += length ;
281317
@@ -286,4 +322,14 @@ void IncreasePosition(int length)
286322 Length = _position ;
287323 }
288324 }
325+
326+ void WriteEmptyBinary ( )
327+ {
328+ EnsureAdditionalCapacity ( 2 ) ;
329+
330+ _buffer [ _position ] = 0 ;
331+ _buffer [ _position + 1 ] = 0 ;
332+
333+ Advance ( 2 ) ;
334+ }
289335}
0 commit comments