1
1
// Copyright (c) .NET Foundation. All rights reserved.
2
2
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
3
4
+ using System ;
5
+ using System . Buffers ;
4
6
using System . Collections . Generic ;
5
7
using System . Globalization ;
6
8
using System . Text ;
@@ -37,12 +39,14 @@ public static Task RenderFortunesHtml(IEnumerable<Fortune> model, HttpContext ht
37
39
38
40
var sb = StringBuilderCache . Acquire ( ) ;
39
41
sb . Append ( "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>" ) ;
42
+
43
+ Span < char > buffer = stackalloc char [ 256 ] ;
40
44
foreach ( var item in model )
41
45
{
42
46
sb . Append ( "<tr><td>" ) ;
43
- sb . Append ( item . Id . ToString ( CultureInfo . InvariantCulture ) ) ;
47
+ sb . Append ( CultureInfo . InvariantCulture , $ " { item . Id } " ) ;
44
48
sb . Append ( "</td><td>" ) ;
45
- sb . Append ( htmlEncoder . Encode ( item . Message ) ) ;
49
+ Encode ( sb , htmlEncoder , item . Message ) ;
46
50
sb . Append ( "</td></tr>" ) ;
47
51
}
48
52
@@ -51,6 +55,18 @@ public static Task RenderFortunesHtml(IEnumerable<Fortune> model, HttpContext ht
51
55
// fortunes includes multibyte characters so response.Length is incorrect
52
56
httpContext . Response . ContentLength = Encoding . UTF8 . GetByteCount ( response ) ;
53
57
return httpContext . Response . WriteAsync ( response ) ;
58
+
59
+ static void Encode ( StringBuilder sb , HtmlEncoder htmlEncoder , string item )
60
+ {
61
+ Span < char > buffer = stackalloc char [ 256 ] ;
62
+ int remaining = item . Length ;
63
+ do
64
+ {
65
+ htmlEncoder . Encode ( item . AsSpan ( ) [ ..remaining ] , buffer , out var consumed , out var written , isFinalBlock : true ) ;
66
+ remaining -= consumed ;
67
+ sb . Append ( buffer . Slice ( 0 , written ) ) ;
68
+ } while ( remaining != 0 ) ;
69
+ }
54
70
}
55
71
}
56
72
}
0 commit comments