@@ -10,19 +10,29 @@ namespace System.Text;
1010/// <summary>Provides downlevel polyfills for span-based Encoding APIs.</summary>
1111internal static class EncodingPolyfills
1212{
13- public static unsafe int GetByteCount ( this Encoding encoding , ReadOnlySpan < char > chars )
13+ public static int GetByteCount ( this Encoding encoding , ReadOnlySpan < char > chars )
1414 {
15- fixed ( char * charsPtr = & GetNonNullPinnableReference ( chars ) )
15+ // SAFETY-TODO: review this unsafe usage.
16+ // Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
17+ unsafe
1618 {
17- return encoding . GetByteCount ( charsPtr , chars . Length ) ;
19+ fixed ( char * charsPtr = & GetNonNullPinnableReference ( chars ) )
20+ {
21+ return encoding . GetByteCount ( charsPtr , chars . Length ) ;
22+ }
1823 }
1924 }
2025
21- public static unsafe int GetCharCount ( this Encoding encoding , ReadOnlySpan < byte > bytes )
26+ public static int GetCharCount ( this Encoding encoding , ReadOnlySpan < byte > bytes )
2227 {
23- fixed ( byte * bytesPtr = & GetNonNullPinnableReference ( bytes ) )
28+ // SAFETY-TODO: review this unsafe usage.
29+ // Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
30+ unsafe
2431 {
25- return encoding . GetCharCount ( bytesPtr , bytes . Length ) ;
32+ fixed ( byte * bytesPtr = & GetNonNullPinnableReference ( bytes ) )
33+ {
34+ return encoding . GetCharCount ( bytesPtr , bytes . Length ) ;
35+ }
2636 }
2737 }
2838
@@ -31,29 +41,44 @@ public static int GetBytes(this Encoding encoding, string str, Span<byte> bytes)
3141 return GetBytes ( encoding , str . AsSpan ( ) , bytes ) ;
3242 }
3343
34- public static unsafe int GetBytes ( this Encoding encoding , ReadOnlySpan < char > chars , Span < byte > bytes )
44+ public static int GetBytes ( this Encoding encoding , ReadOnlySpan < char > chars , Span < byte > bytes )
3545 {
36- fixed ( char * charsPtr = & GetNonNullPinnableReference ( chars ) )
37- fixed ( byte * bytesPtr = & GetNonNullPinnableReference ( bytes ) )
46+ // SAFETY-TODO: review this unsafe usage.
47+ // Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
48+ unsafe
3849 {
39- return encoding . GetBytes ( charsPtr , chars . Length , bytesPtr , bytes . Length ) ;
50+ fixed ( char * charsPtr = & GetNonNullPinnableReference ( chars ) )
51+ fixed ( byte * bytesPtr = & GetNonNullPinnableReference ( bytes ) )
52+ {
53+ return encoding . GetBytes ( charsPtr , chars . Length , bytesPtr , bytes . Length ) ;
54+ }
4055 }
4156 }
4257
43- public static unsafe int GetChars ( this Encoding encoding , ReadOnlySpan < byte > bytes , Span < char > chars )
58+ public static int GetChars ( this Encoding encoding , ReadOnlySpan < byte > bytes , Span < char > chars )
4459 {
45- fixed ( byte * bytesPtr = & GetNonNullPinnableReference ( bytes ) )
46- fixed ( char * charsPtr = & GetNonNullPinnableReference ( chars ) )
60+ // SAFETY-TODO: review this unsafe usage.
61+ // Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
62+ unsafe
4763 {
48- return encoding . GetChars ( bytesPtr , bytes . Length , charsPtr , chars . Length ) ;
64+ fixed ( byte * bytesPtr = & GetNonNullPinnableReference ( bytes ) )
65+ fixed ( char * charsPtr = & GetNonNullPinnableReference ( chars ) )
66+ {
67+ return encoding . GetChars ( bytesPtr , bytes . Length , charsPtr , chars . Length ) ;
68+ }
4969 }
5070 }
5171
52- public static unsafe string GetString ( this Encoding encoding , ReadOnlySpan < byte > bytes )
72+ public static string GetString ( this Encoding encoding , ReadOnlySpan < byte > bytes )
5373 {
54- fixed ( byte * bytesPtr = & GetNonNullPinnableReference ( bytes ) )
74+ // SAFETY-TODO: review this unsafe usage.
75+ // Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
76+ unsafe
5577 {
56- return encoding . GetString ( bytesPtr , bytes . Length ) ;
78+ fixed ( byte * bytesPtr = & GetNonNullPinnableReference ( bytes ) )
79+ {
80+ return encoding . GetString ( bytesPtr , bytes . Length ) ;
81+ }
5782 }
5883 }
5984
@@ -73,9 +98,14 @@ public static bool TryGetChars(this Encoding encoding, ReadOnlySpan<byte> bytes,
7398 }
7499
75100 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
76- private static unsafe ref readonly T GetNonNullPinnableReference < T > ( ReadOnlySpan < T > buffer )
101+ private static ref readonly T GetNonNullPinnableReference < T > ( ReadOnlySpan < T > buffer )
77102 {
78- // Based on the internal implementation from MemoryMarshal.
79- return ref buffer . Length != 0 ? ref MemoryMarshal . GetReference ( buffer ) : ref Unsafe . AsRef < T > ( ( void * ) 1 ) ;
103+ // SAFETY-TODO: review this unsafe usage.
104+ // Either document why it's safe, refactor to remove it, or mark the enclosing member 'unsafe'.
105+ unsafe
106+ {
107+ // Based on the internal implementation from MemoryMarshal.
108+ return ref buffer . Length != 0 ? ref MemoryMarshal . GetReference ( buffer ) : ref Unsafe . AsRef < T > ( ( void * ) 1 ) ;
109+ }
80110 }
81111}
0 commit comments