1- using GenHTTP . Modules . IO . Streaming ;
2-
3- namespace GenHTTP . Engine . Internal . Protocol ;
1+ namespace GenHTTP . Engine . Internal . Protocol ;
42
53/// <summary>
64/// Implements chunked transfer encoding by letting the client
@@ -11,18 +9,8 @@ namespace GenHTTP.Engine.Internal.Protocol;
119/// soon as there is no known content length. To avoid this overhead,
1210/// specify the length of your content whenever possible.
1311/// </remarks>
14- public sealed class ChunkedStream : Stream
12+ public sealed class ChunkedStream ( Stream target ) : Stream
1513{
16- private static readonly string NL = "\r \n " ;
17-
18- #region Initialization
19-
20- public ChunkedStream ( Stream target )
21- {
22- Target = target ;
23- }
24-
25- #endregion
2614
2715 #region Get-/Setters
2816
@@ -36,7 +24,7 @@ public ChunkedStream(Stream target)
3624
3725 public override long Position { get => throw new NotSupportedException ( ) ; set => throw new NotSupportedException ( ) ; }
3826
39- private Stream Target { get ; }
27+ private Stream Target { get ; } = target ;
4028
4129 #endregion
4230
@@ -59,37 +47,37 @@ public override void Write(byte[] buffer, int offset, int count)
5947
6048 Target . Write ( buffer , offset , count ) ;
6149
62- NL . Write ( Target ) ;
50+ Target . Write ( " \r \n "u8 ) ;
6351 }
6452 }
6553
6654 public override async Task WriteAsync ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
6755 {
6856 if ( count > 0 )
6957 {
70- await WriteAsync ( count ) ;
58+ Write ( count ) ;
7159
7260 await Target . WriteAsync ( buffer . AsMemory ( offset , count ) , cancellationToken ) ;
7361
74- await WriteAsync ( NL ) ;
62+ Target . Write ( " \r \n "u8 ) ;
7563 }
7664 }
7765
7866 public override async ValueTask WriteAsync ( ReadOnlyMemory < byte > buffer , CancellationToken cancellationToken = default )
7967 {
8068 if ( ! buffer . IsEmpty )
8169 {
82- await WriteAsync ( buffer . Length ) ;
70+ Write ( buffer . Length ) ;
8371
8472 await Target . WriteAsync ( buffer , cancellationToken ) ;
8573
86- await WriteAsync ( NL ) ;
74+ Target . Write ( " \r \n "u8 ) ;
8775 }
8876 }
8977
90- public async ValueTask FinishAsync ( )
78+ public void Finish ( )
9179 {
92- await WriteAsync ( "0\r \n \r \n " ) ;
80+ Target . Write ( "0\r \n \r \n "u8 ) ;
9381 }
9482
9583 public override void Flush ( )
@@ -99,11 +87,22 @@ public override void Flush()
9987
10088 public override Task FlushAsync ( CancellationToken cancellationToken ) => Target . FlushAsync ( cancellationToken ) ;
10189
102- private void Write ( int value ) => $ "{ value : X} \r \n ". Write ( Target ) ;
90+ private void Write ( int value )
91+ {
92+ Span < byte > buffer = stackalloc byte [ 8 + 2 ] ;
10393
104- private ValueTask WriteAsync ( string text ) => text . WriteAsync ( Target ) ;
94+ if ( value . TryFormat ( buffer , out var written , "X" ) )
95+ {
96+ buffer [ written ++ ] = ( byte ) '\r ' ;
97+ buffer [ written ++ ] = ( byte ) '\n ' ;
10598
106- private ValueTask WriteAsync ( int value ) => $ "{ value : X} \r \n ". WriteAsync ( Target ) ;
99+ Target . Write ( buffer [ ..written ] ) ;
100+ }
101+ else
102+ {
103+ throw new InvalidOperationException ( "Failed to format chunk size" ) ;
104+ }
105+ }
107106
108107 #endregion
109108
0 commit comments