@@ -60,9 +60,9 @@ static int Write7BitEncodedInteger(ref SpanWriter<byte> writer, int value)
6060
6161 internal static int WriteLength ( this IBufferWriter < byte > buffer , int length , LengthFormat lengthFormat )
6262 {
63- var writer = new SpanWriter < byte > ( buffer . GetSpan ( SevenBitEncodedInt . MaxSizeInBytes ) ) ;
64- buffer . Advance ( writer . WriteLength ( length , lengthFormat ) ) ;
65- return writer . WrittenCount ;
63+ var bytesWritten = WriteLength ( buffer . GetSpan ( SevenBitEncodedInt . MaxSizeInBytes ) , length , lengthFormat ) ;
64+ buffer . Advance ( bytesWritten ) ;
65+ return bytesWritten ;
6666 }
6767
6868 internal static int WriteLength ( Span < byte > buffer , int length , LengthFormat lengthFormat )
@@ -71,21 +71,28 @@ internal static int WriteLength(Span<byte> buffer, int length, LengthFormat leng
7171 return writer . WriteLength ( length , lengthFormat ) ;
7272 }
7373
74+ private static int WriteLength ( this ref BufferWriterSlim < byte > buffer , int length , LengthFormat lengthFormat )
75+ {
76+ var bytesWritten = WriteLength ( buffer . GetSpan ( SevenBitEncodedInt . MaxSizeInBytes ) , length , lengthFormat ) ;
77+ buffer . Advance ( bytesWritten ) ;
78+ return bytesWritten ;
79+ }
80+
7481 /// <summary>
7582 /// Encodes string using the specified encoding.
7683 /// </summary>
7784 /// <param name="writer">The buffer writer.</param>
78- /// <param name="value ">The sequence of characters.</param>
85+ /// <param name="chars ">The sequence of characters.</param>
7986 /// <param name="context">The encoding context.</param>
8087 /// <param name="lengthFormat">String length encoding format; or <see langword="null"/> to prevent encoding of string length.</param>
8188 /// <returns>The number of written bytes.</returns>
82- public static long Encode ( this IBufferWriter < byte > writer , ReadOnlySpan < char > value , in EncodingContext context , LengthFormat ? lengthFormat = null )
89+ public static long Encode ( this IBufferWriter < byte > writer , ReadOnlySpan < char > chars , in EncodingContext context , LengthFormat ? lengthFormat = null )
8390 {
8491 var result = lengthFormat . HasValue
85- ? writer . WriteLength ( context . Encoding . GetByteCount ( value ) , lengthFormat . GetValueOrDefault ( ) )
92+ ? writer . WriteLength ( context . Encoding . GetByteCount ( chars ) , lengthFormat . GetValueOrDefault ( ) )
8693 : 0L ;
8794
88- context . GetEncoder ( ) . Convert ( value , writer , true , out var bytesWritten , out _ ) ;
95+ context . GetEncoder ( ) . Convert ( chars , writer , true , out var bytesWritten , out _ ) ;
8996 result += bytesWritten ;
9097
9198 return result ;
@@ -95,19 +102,19 @@ public static long Encode(this IBufferWriter<byte> writer, ReadOnlySpan<char> va
95102 /// Encodes string using the specified encoding.
96103 /// </summary>
97104 /// <param name="writer">The buffer writer.</param>
98- /// <param name="value ">The sequence of characters.</param>
105+ /// <param name="chars ">The sequence of characters.</param>
99106 /// <param name="context">The encoding context.</param>
100107 /// <param name="lengthFormat">String length encoding format; or <see langword="null"/> to prevent encoding of string length.</param>
101108 /// <returns>The number of written bytes.</returns>
102- public static int Encode ( this ref SpanWriter < byte > writer , ReadOnlySpan < char > value , in EncodingContext context , LengthFormat ? lengthFormat = null )
109+ public static int Encode ( this ref SpanWriter < byte > writer , scoped ReadOnlySpan < char > chars , in EncodingContext context , LengthFormat ? lengthFormat = null )
103110 {
104111 var result = lengthFormat . HasValue
105- ? writer . WriteLength ( context . Encoding . GetByteCount ( value ) , lengthFormat . GetValueOrDefault ( ) )
112+ ? writer . WriteLength ( context . Encoding . GetByteCount ( chars ) , lengthFormat . GetValueOrDefault ( ) )
106113 : 0 ;
107114
108115 var bytesWritten = context . TryGetEncoder ( ) is { } encoder
109- ? encoder . GetBytes ( value , writer . RemainingSpan , flush : true )
110- : context . Encoding . GetBytes ( value , writer . RemainingSpan ) ;
116+ ? encoder . GetBytes ( chars , writer . RemainingSpan , flush : true )
117+ : context . Encoding . GetBytes ( chars , writer . RemainingSpan ) ;
111118 result += bytesWritten ;
112119 writer . Advance ( bytesWritten ) ;
113120
@@ -128,6 +135,66 @@ public static int Write(this ref SpanWriter<byte> writer, scoped ReadOnlySpan<by
128135
129136 return result ;
130137 }
138+
139+ /// <summary>
140+ /// Encodes string using the specified encoding.
141+ /// </summary>
142+ /// <param name="writer">The buffer writer.</param>
143+ /// <param name="chars">The sequence of characters.</param>
144+ /// <param name="context">The encoding context.</param>
145+ /// <param name="lengthFormat">String length encoding format; or <see langword="null"/> to prevent encoding of string length.</param>
146+ /// <returns>The number of written bytes.</returns>
147+ public static int Encode ( this ref BufferWriterSlim < byte > writer , scoped ReadOnlySpan < char > chars , in EncodingContext context ,
148+ LengthFormat ? lengthFormat = null )
149+ {
150+ Span < byte > buffer ;
151+ int byteCount , result ;
152+ if ( lengthFormat . HasValue )
153+ {
154+ byteCount = context . Encoding . GetByteCount ( chars ) ;
155+ result = writer . WriteLength ( byteCount , lengthFormat . GetValueOrDefault ( ) ) ;
156+
157+ buffer = writer . GetSpan ( byteCount ) ;
158+ byteCount = context . TryGetEncoder ( ) is { } encoder
159+ ? encoder . GetBytes ( chars , buffer , flush : true )
160+ : context . Encoding . GetBytes ( chars , buffer ) ;
161+
162+ result += byteCount ;
163+ writer . Advance ( byteCount ) ;
164+ }
165+ else
166+ {
167+ result = 0 ;
168+ var encoder = context . GetEncoder ( ) ;
169+ byteCount = context . Encoding . GetMaxByteCount ( 1 ) ;
170+ for ( int charsUsed , bytesWritten ; ! chars . IsEmpty ; chars = chars . Slice ( charsUsed ) , result += bytesWritten )
171+ {
172+ buffer = writer . GetSpan ( byteCount ) ;
173+ var maxChars = buffer . Length / byteCount ;
174+
175+ encoder . Convert ( chars , buffer , chars . Length <= maxChars , out charsUsed , out bytesWritten , out _ ) ;
176+ writer . Advance ( bytesWritten ) ;
177+ }
178+ }
179+
180+ return result ;
181+ }
182+
183+ /// <summary>
184+ /// Writes a sequence of bytes prefixed with the length.
185+ /// </summary>
186+ /// <param name="writer">The buffer writer.</param>
187+ /// <param name="value">A sequence of bytes to be written.</param>
188+ /// <param name="lengthFormat">A format of the buffer length to be written.</param>
189+ /// <returns>A number of bytes written.</returns>
190+ public static int Write ( this ref BufferWriterSlim < byte > writer , scoped ReadOnlySpan < byte > value , LengthFormat lengthFormat )
191+ {
192+ var result = writer . WriteLength ( value . Length , lengthFormat ) ;
193+ writer . Write ( value ) ;
194+ result += value . Length ;
195+
196+ return result ;
197+ }
131198
132199 private static bool TryFormat < T > ( IBufferWriter < byte > writer , T value , Span < char > buffer , in EncodingContext context , LengthFormat ? lengthFormat , ReadOnlySpan < char > format , IFormatProvider ? provider , out long bytesWritten )
133200 where T : notnull , ISpanFormattable
0 commit comments