22
33#pragma warning disable IDE0079
44#pragma warning disable SA1121
5-
6- namespace Asp . Versioning ;
5+ #pragma warning disable SA1135
6+ #pragma warning disable SA1200
77
88#if NETFRAMEWORK
99using System . Net . Http . Headers ;
10+ using HttpRequest = System . Net . Http . HttpRequestMessage ;
11+ using MediaTypeHeaderValue = System . Net . Http . Headers . MediaTypeWithQualityHeaderValue ;
1012#else
1113using Microsoft . AspNetCore . Http ;
14+ using Microsoft . Net . Http . Headers ;
15+ #endif
16+
17+ namespace Asp . Versioning ;
18+
19+ #if ! NETFRAMEWORK
1220using System . Buffers ;
1321#endif
1422using System . Runtime . CompilerServices ;
1523using System . Text . RegularExpressions ;
1624#if NETFRAMEWORK
17- using HttpRequest = System . Net . Http . HttpRequestMessage ;
1825using Str = System . String ;
1926using StrComparer = System . StringComparer ;
2027#else
21- using MediaTypeWithQualityHeaderValue = Microsoft . Net . Http . Headers . MediaTypeHeaderValue ;
2228using Str = Microsoft . Extensions . Primitives . StringSegment ;
2329using StrComparer = Microsoft . Extensions . Primitives . StringSegmentComparer ;
2430#endif
2531using static Asp . Versioning . ApiVersionParameterLocation ;
2632using static System . StringComparison ;
33+ using ReaderCallback = Func < IReadOnlyList < MediaTypeHeaderValue > , IReadOnlyList < string > > ;
34+ using SelectorCallback = Func < HttpRequest , IReadOnlyList < string > , IReadOnlyList < string > > ;
2735
2836/// <summary>
2937/// Represents a builder for an API version reader that reads the value from a media type HTTP header in the request.
@@ -33,8 +41,8 @@ public partial class MediaTypeApiVersionReaderBuilder
3341 private HashSet < string > ? parameters ;
3442 private HashSet < Str > ? included ;
3543 private HashSet < Str > ? excluded ;
36- private Func < HttpRequest , IReadOnlyList < string > , IReadOnlyList < string > > ? select ;
37- private List < Func < IReadOnlyList < MediaTypeWithQualityHeaderValue > , IReadOnlyList < string > > > ? readers ;
44+ private SelectorCallback ? select ;
45+ private List < ReaderCallback > ? readers ;
3846
3947 /// <summary>
4048 /// Adds the name of a media type parameter to be read.
@@ -114,7 +122,7 @@ public virtual MediaTypeApiVersionReaderBuilder Match( [StringSyntax( StringSynt
114122 [ CLSCompliant ( false ) ]
115123#endif
116124#pragma warning disable CA1716 // Identifiers should not match keywords
117- public virtual MediaTypeApiVersionReaderBuilder Select ( Func < HttpRequest , IReadOnlyList < string > , IReadOnlyList < string > > selector )
125+ public virtual MediaTypeApiVersionReaderBuilder Select ( SelectorCallback selector )
118126#pragma warning restore CA1716 // Identifiers should not match keywords
119127 {
120128 select = selector ;
@@ -149,7 +157,7 @@ public virtual IApiVersionReader Build() =>
149157#if ! NETFRAMEWORK
150158 [ CLSCompliant ( false ) ]
151159#endif
152- protected void AddReader( Func < IReadOnlyList < MediaTypeWithQualityHeaderValue > , IReadOnlyList < string > > reader )
160+ protected void AddReader( ReaderCallback reader )
153161 {
154162 ArgumentNullException . ThrowIfNull ( reader ) ;
155163
@@ -158,23 +166,29 @@ protected void AddReader( Func<IReadOnlyList<MediaTypeWithQualityHeaderValue>, I
158166 }
159167
160168 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
161- private static ICollection < Str > EmptyCollection ( ) => Array . Empty < Str > ( ) ;
169+ private static IReadOnlyList < string > DefaultSelector ( HttpRequest request , IReadOnlyList < string > versions ) => versions ;
162170
163171 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
164- private static IReadOnlyList< Func < IReadOnlyList < MediaTypeWithQualityHeaderValue > , IReadOnlyList < string > > > EmptyList ( ) =>
165- Array . Empty < Func < IReadOnlyList < MediaTypeWithQualityHeaderValue > , IReadOnlyList < string > > > ( ) ;
172+ private static string[ ] ToArray ( ref string ? version, List < string > ? versions )
173+ {
174+ if ( version is null )
175+ {
176+ return [ ] ;
177+ }
166178
167- private static IReadOnlyList < string > DefaultSelector ( HttpRequest request , IReadOnlyList < string > versions ) => versions ;
179+ return versions is null ? [ version ] : [ .. versions ] ;
180+ }
168181
169- private static IReadOnlyList < string > ReadMediaType (
170- IReadOnlyList < MediaTypeWithQualityHeaderValue > mediaTypes ,
182+ private static string [ ] ReadMediaType (
183+ IReadOnlyList < MediaTypeHeaderValue > mediaTypes ,
171184 string pattern )
172185 {
173186 var version = default ( string ) ;
174187 var versions = default ( List < string > ) ;
175188 var regex = default ( Regex ) ;
189+ var count = mediaTypes. Count;
176190
177- for ( var i = 0 ; i < mediaTypes . Count ; i ++ )
191+ for ( var i = 0 ; i < count ; i++ )
178192 {
179193 var mediaType = mediaTypes[ i ] . MediaType ;
180194
@@ -203,7 +217,7 @@ private static IReadOnlyList<string> ReadMediaType(
203217 }
204218 else if ( versions = = null )
205219 {
206- versions = new ( capacity : mediaTypes . Count - i + 1 )
220+ versions = new ( capacity : count - i + 1 )
207221 {
208222 version ,
209223 value ,
@@ -218,22 +232,18 @@ private static IReadOnlyList<string> ReadMediaType(
218232 }
219233 }
220234
221- if ( version is null )
222- {
223- return Array . Empty < string > ( ) ;
224- }
225-
226- return versions is null ? new [ ] { version } : versions . ToArray ( ) ;
235+ return ToArray( ref version , versions ) ;
227236 }
228237
229- private static IReadOnlyList < string > ReadMediaTypeParameter (
230- IReadOnlyList < MediaTypeWithQualityHeaderValue > mediaTypes ,
238+ private static string [ ] ReadMediaTypeParameter (
239+ IReadOnlyList < MediaTypeHeaderValue > mediaTypes ,
231240 string parameterName )
232241 {
233242 var version = default ( string ) ;
234243 var versions = default ( List < string > ) ;
244+ var count = mediaTypes. Count;
235245
236- for ( var i = 0 ; i < mediaTypes . Count ; i ++ )
246+ for ( var i = 0 ; i < count ; i++ )
237247 {
238248 var mediaType = mediaTypes[ i] ;
239249
@@ -256,7 +266,7 @@ private static IReadOnlyList<string> ReadMediaTypeParameter(
256266 }
257267 else if ( versions = = null )
258268 {
259- versions = new ( capacity : mediaTypes . Count - i + 1 )
269+ versions = new ( capacity : count - i + 1 )
260270 {
261271 version ,
262272 value ,
@@ -269,28 +279,23 @@ private static IReadOnlyList<string> ReadMediaTypeParameter(
269279 }
270280 }
271281
272- if ( version is null )
273- {
274- return Array . Empty < string > ( ) ;
275- }
276-
277- return versions is null ? new [ ] { version } : versions . ToArray ( ) ;
282+ return ToArray( ref version , versions ) ;
278283 }
279284
280285 private sealed class BuiltMediaTypeApiVersionReader : IApiVersionReader
281286 {
282- private readonly IReadOnlyList < string > parameters ;
283- private readonly ICollection < Str > included ;
284- private readonly ICollection < Str > excluded ;
285- private readonly Func < HttpRequest , IReadOnlyList < string > , IReadOnlyList < string > > selector ;
286- private readonly IReadOnlyList < Func < IReadOnlyList < MediaTypeWithQualityHeaderValue > , IReadOnlyList < string > > > readers ;
287+ private readonly string [ ] parameters ;
288+ private readonly HashSet < Str > included ;
289+ private readonly HashSet < Str > excluded ;
290+ private readonly SelectorCallback selector;
291+ private readonly ReaderCallback [ ] readers ;
287292
288293 internal BuiltMediaTypeApiVersionReader(
289- IReadOnlyList < string > parameters,
290- ICollection < Str> included,
291- ICollection < Str> excluded,
292- Func < HttpRequest , IReadOnlyList < string > , IReadOnlyList < string >> selector,
293- IReadOnlyList < Func < IReadOnlyList < MediaTypeWithQualityHeaderValue > , IReadOnlyList < string >>> readers )
294+ string [ ] parameters ,
295+ HashSet < Str > included ,
296+ HashSet < Str > excluded ,
297+ SelectorCallback selector ,
298+ ReaderCallback [ ] readers )
294299 {
295300 this . parameters = parameters ;
296301 this . included = included ;
@@ -301,18 +306,15 @@ internal BuiltMediaTypeApiVersionReader(
301306
302307 public void AddParameters ( IApiVersionParameterDescriptionContext context )
303308 {
304- if ( context == null )
305- {
306- throw new ArgumentNullException ( nameof ( context ) ) ;
307- }
309+ ArgumentNullException . ThrowIfNull ( context ) ;
308310
309- if ( parameters . Count == 0 )
311+ if ( parameters . Length == 0 )
310312 {
311313 context. AddParameter ( name : string . Empty , MediaTypeParameter ) ;
312314 }
313315 else
314316 {
315- for ( var i = 0 ; i < parameters . Count ; i ++ )
317+ for ( var i = 0 ; i < parameters . Length ; i++ )
316318 {
317319 context . AddParameter ( parameters [ i ] , MediaTypeParameter ) ;
318320 }
@@ -321,30 +323,29 @@ public void AddParameters( IApiVersionParameterDescriptionContext context )
321323
322324 public IReadOnlyList< string > Read ( HttpRequest request )
323325 {
324- if ( readers . Count == 0 )
326+ if ( readers . Length == 0 )
325327 {
326328 return Array. Empty < string > ( ) ;
327329 }
328330
329331#if NETFRAMEWORK
330332 var headers = request. Headers ;
331333 var contentType = request . Content ? . Headers . ContentType ;
332- var accept = headers . Accept ;
333334#else
334335 var headers = request . GetTypedHeaders ( ) ;
335336 var contentType = headers . ContentType ;
336- var accept = headers . Accept ;
337337#endif
338+ var accept = headers . Accept ;
338339 var version = default ( string ) ;
339340 var versions = default ( SortedSet < string > ) ;
340- var mediaTypes = default ( List < MediaTypeWithQualityHeaderValue > ) ;
341+ var mediaTypes = default ( List < MediaTypeHeaderValue > ) ;
341342
342343 if ( contentType != null )
343344 {
344345#if NETFRAMEWORK
345- mediaTypes = new ( ) { MediaTypeWithQualityHeaderValue . Parse ( contentType . ToString ( ) ) } ;
346+ mediaTypes = [ MediaTypeHeaderValue . Parse ( contentType . ToString ( ) ) ] ;
346347#else
347- mediaTypes = new ( ) { contentType } ;
348+ mediaTypes = [ contentType ] ;
348349#endif
349350 }
350351
@@ -376,13 +377,13 @@ public IReadOnlyList<string> Read( HttpRequest request )
376377
377378 if ( versions == null )
378379 {
379- return version == null ? Array . Empty < string > ( ) : new [ ] { version } ;
380+ return version == null ? Array . Empty < string > ( ) : [ version ] ;
380381 }
381382
382383 return selector( request , versions . ToArray ( ) ) ;
383384 }
384385
385- private void Filter ( IList < MediaTypeWithQualityHeaderValue > mediaTypes )
386+ private void Filter( List < MediaTypeHeaderValue > mediaTypes )
386387 {
387388 if ( excluded . Count > 0 )
388389 {
@@ -412,11 +413,11 @@ private void Filter( IList<MediaTypeWithQualityHeaderValue> mediaTypes )
412413 }
413414
414415 private void Read(
415- List < MediaTypeWithQualityHeaderValue > mediaTypes ,
416+ IReadOnlyList < MediaTypeHeaderValue > mediaTypes,
416417 ref string ? version,
417418 ref SortedSet< string > ? versions )
418419 {
419- for ( var i = 0 ; i < readers . Count ; i ++ )
420+ for ( var i = 0 ; i < readers. Length ; i++ )
420421 {
421422 var result = readers[ i] ( mediaTypes ) ;
422423
0 commit comments