@@ -32,14 +32,34 @@ public static class Utf8JsonReaderHelper
3232 out T ? result )
3333 where T : IObjectFactory < T , ReadOnlySpan < char > , TValidationError >
3434 where TValidationError : class , IValidationError < TValidationError >
35+ {
36+ return ValidateFromUtf8 < T , TValidationError , ObjectFactoryAdapter < T , TValidationError > > (
37+ ref reader , provider , default , out result ) ;
38+ }
39+
40+ /// <summary>
41+ /// This is an internal API that supports the Thinktecture.Runtime.Extensions infrastructure and not subject to
42+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
43+ /// any release. You should only use it directly in your code with extreme caution and knowing that
44+ /// doing so can result in application failures when updating to a new Thinktecture.Runtime.Extensions release.
45+ /// </summary>
46+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
47+ public static TValidationError ? ValidateFromUtf8 < T , TValidationError , TFactory > (
48+ ref Utf8JsonReader reader ,
49+ IFormatProvider ? provider ,
50+ TFactory factory ,
51+ out T ? result )
52+ where T : notnull
53+ where TValidationError : class , IValidationError < TValidationError >
54+ where TFactory : struct , IUtf8JsonFactory < T , TValidationError >
3555 {
3656 // Escaped values (rarest case): CopyString handles unescaping and reassembly
3757 if ( reader . ValueIsEscaped )
38- return ValidateEscaped < T , TValidationError > ( ref reader , provider , out result ) ;
58+ return ValidateEscaped < T , TValidationError , TFactory > ( ref reader , provider , factory , out result ) ;
3959
4060 // Fragmented but not escaped: assemble bytes, then transcode
4161 if ( reader . HasValueSequence )
42- return ValidateFragmentedUnescaped < T , TValidationError > ( ref reader , provider , out result ) ;
62+ return ValidateFragmentedUnescaped < T , TValidationError , TFactory > ( ref reader , provider , factory , out result ) ;
4363
4464 // Fast path: contiguous, unescaped, short value (most common case)
4565 var utf8Bytes = reader . ValueSpan ;
@@ -49,29 +69,31 @@ public static class Utf8JsonReaderHelper
4969 // Constant size enables JIT to emit a simple stack bump instead of localloc
5070 Span < char > charBuf = stackalloc char [ _STACKALLOC_CHAR_THRESHOLD ] ;
5171 var charsWritten = Encoding . UTF8 . GetChars ( utf8Bytes , charBuf ) ;
52- return T . Validate ( charBuf [ ..charsWritten ] , provider , out result ) ;
72+ return factory . Validate ( charBuf [ ..charsWritten ] , provider , out result ) ;
5373 }
5474
5575 // Large contiguous unescaped value
56- return ValidateLargeContiguousValue < T , TValidationError > ( utf8Bytes , provider , out result ) ;
76+ return ValidateLargeContiguousValue < T , TValidationError , TFactory > ( utf8Bytes , provider , factory , out result ) ;
5777 }
5878
5979 // NoInlining: keeps the try/finally and ArrayPool machinery out of ValidateFromUtf8's inlined body,
6080 // ensuring the JIT emits compact native code for the hot stackalloc path.
6181 [ MethodImpl ( MethodImplOptions . NoInlining ) ]
62- private static TValidationError ? ValidateLargeContiguousValue < T , TValidationError > (
82+ private static TValidationError ? ValidateLargeContiguousValue < T , TValidationError , TFactory > (
6383 ReadOnlySpan < byte > utf8Bytes ,
6484 IFormatProvider ? provider ,
85+ TFactory factory ,
6586 out T ? result )
66- where T : IObjectFactory < T , ReadOnlySpan < char > , TValidationError >
87+ where T : notnull
6788 where TValidationError : class , IValidationError < TValidationError >
89+ where TFactory : struct , IUtf8JsonFactory < T , TValidationError >
6890 {
6991 var rentedChars = ArrayPool < char > . Shared . Rent ( utf8Bytes . Length ) ;
7092
7193 try
7294 {
7395 var charsWritten = Encoding . UTF8 . GetChars ( utf8Bytes , rentedChars ) ;
74- return T . Validate ( rentedChars . AsSpan ( 0 , charsWritten ) , provider , out result ) ;
96+ return factory . Validate ( rentedChars . AsSpan ( 0 , charsWritten ) , provider , out result ) ;
7597 }
7698 finally
7799 {
@@ -82,12 +104,14 @@ public static class Utf8JsonReaderHelper
82104 // NoInlining: fragmented values are rare; isolating this keeps ValidateFromUtf8's
83105 // inlined body compact and avoids polluting the caller with ArrayPool<byte> machinery.
84106 [ MethodImpl ( MethodImplOptions . NoInlining ) ]
85- private static TValidationError ? ValidateFragmentedUnescaped < T , TValidationError > (
107+ private static TValidationError ? ValidateFragmentedUnescaped < T , TValidationError , TFactory > (
86108 ref Utf8JsonReader reader ,
87109 IFormatProvider ? provider ,
110+ TFactory factory ,
88111 out T ? result )
89- where T : IObjectFactory < T , ReadOnlySpan < char > , TValidationError >
112+ where T : notnull
90113 where TValidationError : class , IValidationError < TValidationError >
114+ where TFactory : struct , IUtf8JsonFactory < T , TValidationError >
91115 {
92116 var sequence = reader . ValueSequence ;
93117 var byteLength = checked ( ( int ) sequence . Length ) ;
@@ -104,15 +128,15 @@ public static class Utf8JsonReaderHelper
104128 {
105129 Span < char > charBuf = stackalloc char [ _STACKALLOC_CHAR_THRESHOLD ] ;
106130 var charsWritten = Encoding . UTF8 . GetChars ( utf8Bytes , charBuf ) ;
107- return T . Validate ( charBuf [ ..charsWritten ] , provider , out result ) ;
131+ return factory . Validate ( charBuf [ ..charsWritten ] , provider , out result ) ;
108132 }
109133
110134 var rentedChars = ArrayPool < char > . Shared . Rent ( byteLength ) ;
111135
112136 try
113137 {
114138 var charsWritten = Encoding . UTF8 . GetChars ( utf8Bytes , rentedChars ) ;
115- return T . Validate ( rentedChars . AsSpan ( 0 , charsWritten ) , provider , out result ) ;
139+ return factory . Validate ( rentedChars . AsSpan ( 0 , charsWritten ) , provider , out result ) ;
116140 }
117141 finally
118142 {
@@ -127,12 +151,14 @@ public static class Utf8JsonReaderHelper
127151
128152 // NoInlining: escaped values are the rarest case; isolating this keeps the dispatch compact.
129153 [ MethodImpl ( MethodImplOptions . NoInlining ) ]
130- private static TValidationError ? ValidateEscaped < T , TValidationError > (
154+ private static TValidationError ? ValidateEscaped < T , TValidationError , TFactory > (
131155 ref Utf8JsonReader reader ,
132156 IFormatProvider ? provider ,
157+ TFactory factory ,
133158 out T ? result )
134- where T : IObjectFactory < T , ReadOnlySpan < char > , TValidationError >
159+ where T : notnull
135160 where TValidationError : class , IValidationError < TValidationError >
161+ where TFactory : struct , IUtf8JsonFactory < T , TValidationError >
136162 {
137163 // CopyString handles both unescaping and reassembly of fragmented sequences
138164 var byteLength = reader . HasValueSequence
@@ -143,15 +169,15 @@ public static class Utf8JsonReaderHelper
143169 {
144170 Span < char > charBuf = stackalloc char [ _STACKALLOC_CHAR_THRESHOLD ] ;
145171 var charsWritten = reader . CopyString ( charBuf ) ;
146- return T . Validate ( charBuf [ ..charsWritten ] , provider , out result ) ;
172+ return factory . Validate ( charBuf [ ..charsWritten ] , provider , out result ) ;
147173 }
148174
149175 var rentedChars = ArrayPool < char > . Shared . Rent ( byteLength ) ;
150176
151177 try
152178 {
153179 var charsWritten = reader . CopyString ( rentedChars ) ;
154- return T . Validate ( rentedChars . AsSpan ( 0 , charsWritten ) , provider , out result ) ;
180+ return factory . Validate ( rentedChars . AsSpan ( 0 , charsWritten ) , provider , out result ) ;
155181 }
156182 finally
157183 {
0 commit comments