diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs index dced5163a69..239420f96d8 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -7807,450 +7807,266 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { switch (_next) { - case 0: - goto HeaderAccept; - case 1: - goto HeaderConnection; - case 2: - goto HeaderHost; - case 3: - goto HeaderUserAgent; - case 4: - goto HeaderAuthority; - case 5: - goto HeaderMethod; - case 6: - goto HeaderPath; - case 7: - goto HeaderScheme; - case 8: - goto HeaderAcceptCharset; - case 9: - goto HeaderAcceptEncoding; - case 10: - goto HeaderAcceptLanguage; - case 11: - goto HeaderAccessControlRequestHeaders; - case 12: - goto HeaderAccessControlRequestMethod; - case 13: - goto HeaderAuthorization; - case 14: - goto HeaderBaggage; - case 15: - goto HeaderCacheControl; - case 16: - goto HeaderContentType; - case 17: - goto HeaderCookie; - case 18: - goto HeaderCorrelationContext; - case 19: - goto HeaderDate; - case 20: - goto HeaderExpect; - case 21: - goto HeaderFrom; - case 22: - goto HeaderGrpcAcceptEncoding; - case 23: - goto HeaderGrpcEncoding; - case 24: - goto HeaderGrpcTimeout; - case 25: - goto HeaderIfMatch; - case 26: - goto HeaderIfModifiedSince; - case 27: - goto HeaderIfNoneMatch; - case 28: - goto HeaderIfRange; - case 29: - goto HeaderIfUnmodifiedSince; - case 30: - goto HeaderKeepAlive; - case 31: - goto HeaderMaxForwards; - case 32: - goto HeaderOrigin; - case 33: - goto HeaderPragma; - case 34: - goto HeaderProxyAuthorization; - case 35: - goto HeaderRange; - case 36: - goto HeaderReferer; - case 37: - goto HeaderRequestId; - case 38: - goto HeaderTE; - case 39: - goto HeaderTraceParent; - case 40: - goto HeaderTraceState; - case 41: - goto HeaderTransferEncoding; - case 42: - goto HeaderTranslate; - case 43: - goto HeaderUpgrade; - case 44: - goto HeaderUpgradeInsecureRequests; - case 45: - goto HeaderVia; - case 46: - goto HeaderWarning; - case 47: - goto HeaderContentLength; - default: - goto ExtraHeaders; - } - - HeaderAccept: // case 0 - if ((_bits & 0x1L) != 0) - { + case 0: // Header: "Accept" + Debug.Assert((_currentBits & 0x1L) != 0); _current = new KeyValuePair(HeaderNames.Accept, _collection._headers._Accept); - _next = 1; - return true; - } - HeaderConnection: // case 1 - if ((_bits & 0x2L) != 0) - { + _currentBits ^= 0x1L; + break; + case 1: // Header: "Connection" + Debug.Assert((_currentBits & 0x2L) != 0); _current = new KeyValuePair(HeaderNames.Connection, _collection._headers._Connection); - _next = 2; - return true; - } - HeaderHost: // case 2 - if ((_bits & 0x4L) != 0) - { + _currentBits ^= 0x2L; + break; + case 2: // Header: "Host" + Debug.Assert((_currentBits & 0x4L) != 0); _current = new KeyValuePair(HeaderNames.Host, _collection._headers._Host); - _next = 3; - return true; - } - HeaderUserAgent: // case 3 - if ((_bits & 0x8L) != 0) - { + _currentBits ^= 0x4L; + break; + case 3: // Header: "User-Agent" + Debug.Assert((_currentBits & 0x8L) != 0); _current = new KeyValuePair(HeaderNames.UserAgent, _collection._headers._UserAgent); - _next = 4; - return true; - } - HeaderAuthority: // case 4 - if ((_bits & 0x10L) != 0) - { + _currentBits ^= 0x8L; + break; + case 4: // Header: ":authority" + Debug.Assert((_currentBits & 0x10L) != 0); _current = new KeyValuePair(HeaderNames.Authority, _collection._headers._Authority); - _next = 5; - return true; - } - HeaderMethod: // case 5 - if ((_bits & 0x20L) != 0) - { + _currentBits ^= 0x10L; + break; + case 5: // Header: ":method" + Debug.Assert((_currentBits & 0x20L) != 0); _current = new KeyValuePair(HeaderNames.Method, _collection._headers._Method); - _next = 6; - return true; - } - HeaderPath: // case 6 - if ((_bits & 0x40L) != 0) - { + _currentBits ^= 0x20L; + break; + case 6: // Header: ":path" + Debug.Assert((_currentBits & 0x40L) != 0); _current = new KeyValuePair(HeaderNames.Path, _collection._headers._Path); - _next = 7; - return true; - } - HeaderScheme: // case 7 - if ((_bits & 0x80L) != 0) - { + _currentBits ^= 0x40L; + break; + case 7: // Header: ":scheme" + Debug.Assert((_currentBits & 0x80L) != 0); _current = new KeyValuePair(HeaderNames.Scheme, _collection._headers._Scheme); - _next = 8; - return true; - } - HeaderAcceptCharset: // case 8 - if ((_bits & 0x100L) != 0) - { + _currentBits ^= 0x80L; + break; + case 8: // Header: "Accept-Charset" + Debug.Assert((_currentBits & 0x100L) != 0); _current = new KeyValuePair(HeaderNames.AcceptCharset, _collection._headers._AcceptCharset); - _next = 9; - return true; - } - HeaderAcceptEncoding: // case 9 - if ((_bits & 0x200L) != 0) - { + _currentBits ^= 0x100L; + break; + case 9: // Header: "Accept-Encoding" + Debug.Assert((_currentBits & 0x200L) != 0); _current = new KeyValuePair(HeaderNames.AcceptEncoding, _collection._headers._AcceptEncoding); - _next = 10; - return true; - } - HeaderAcceptLanguage: // case 10 - if ((_bits & 0x400L) != 0) - { + _currentBits ^= 0x200L; + break; + case 10: // Header: "Accept-Language" + Debug.Assert((_currentBits & 0x400L) != 0); _current = new KeyValuePair(HeaderNames.AcceptLanguage, _collection._headers._AcceptLanguage); - _next = 11; - return true; - } - HeaderAccessControlRequestHeaders: // case 11 - if ((_bits & 0x800L) != 0) - { + _currentBits ^= 0x400L; + break; + case 11: // Header: "Access-Control-Request-Headers" + Debug.Assert((_currentBits & 0x800L) != 0); _current = new KeyValuePair(HeaderNames.AccessControlRequestHeaders, _collection._headers._AccessControlRequestHeaders); - _next = 12; - return true; - } - HeaderAccessControlRequestMethod: // case 12 - if ((_bits & 0x1000L) != 0) - { + _currentBits ^= 0x800L; + break; + case 12: // Header: "Access-Control-Request-Method" + Debug.Assert((_currentBits & 0x1000L) != 0); _current = new KeyValuePair(HeaderNames.AccessControlRequestMethod, _collection._headers._AccessControlRequestMethod); - _next = 13; - return true; - } - HeaderAuthorization: // case 13 - if ((_bits & 0x2000L) != 0) - { + _currentBits ^= 0x1000L; + break; + case 13: // Header: "Authorization" + Debug.Assert((_currentBits & 0x2000L) != 0); _current = new KeyValuePair(HeaderNames.Authorization, _collection._headers._Authorization); - _next = 14; - return true; - } - HeaderBaggage: // case 14 - if ((_bits & 0x4000L) != 0) - { + _currentBits ^= 0x2000L; + break; + case 14: // Header: "baggage" + Debug.Assert((_currentBits & 0x4000L) != 0); _current = new KeyValuePair(HeaderNames.Baggage, _collection._headers._Baggage); - _next = 15; - return true; - } - HeaderCacheControl: // case 15 - if ((_bits & 0x8000L) != 0) - { + _currentBits ^= 0x4000L; + break; + case 15: // Header: "Cache-Control" + Debug.Assert((_currentBits & 0x8000L) != 0); _current = new KeyValuePair(HeaderNames.CacheControl, _collection._headers._CacheControl); - _next = 16; - return true; - } - HeaderContentType: // case 16 - if ((_bits & 0x10000L) != 0) - { + _currentBits ^= 0x8000L; + break; + case 16: // Header: "Content-Type" + Debug.Assert((_currentBits & 0x10000L) != 0); _current = new KeyValuePair(HeaderNames.ContentType, _collection._headers._ContentType); - _next = 17; - return true; - } - HeaderCookie: // case 17 - if ((_bits & 0x20000L) != 0) - { + _currentBits ^= 0x10000L; + break; + case 17: // Header: "Cookie" + Debug.Assert((_currentBits & 0x20000L) != 0); _current = new KeyValuePair(HeaderNames.Cookie, _collection._headers._Cookie); - _next = 18; - return true; - } - HeaderCorrelationContext: // case 18 - if ((_bits & 0x40000L) != 0) - { + _currentBits ^= 0x20000L; + break; + case 18: // Header: "Correlation-Context" + Debug.Assert((_currentBits & 0x40000L) != 0); _current = new KeyValuePair(HeaderNames.CorrelationContext, _collection._headers._CorrelationContext); - _next = 19; - return true; - } - HeaderDate: // case 19 - if ((_bits & 0x80000L) != 0) - { + _currentBits ^= 0x40000L; + break; + case 19: // Header: "Date" + Debug.Assert((_currentBits & 0x80000L) != 0); _current = new KeyValuePair(HeaderNames.Date, _collection._headers._Date); - _next = 20; - return true; - } - HeaderExpect: // case 20 - if ((_bits & 0x100000L) != 0) - { + _currentBits ^= 0x80000L; + break; + case 20: // Header: "Expect" + Debug.Assert((_currentBits & 0x100000L) != 0); _current = new KeyValuePair(HeaderNames.Expect, _collection._headers._Expect); - _next = 21; - return true; - } - HeaderFrom: // case 21 - if ((_bits & 0x200000L) != 0) - { + _currentBits ^= 0x100000L; + break; + case 21: // Header: "From" + Debug.Assert((_currentBits & 0x200000L) != 0); _current = new KeyValuePair(HeaderNames.From, _collection._headers._From); - _next = 22; - return true; - } - HeaderGrpcAcceptEncoding: // case 22 - if ((_bits & 0x400000L) != 0) - { + _currentBits ^= 0x200000L; + break; + case 22: // Header: "Grpc-Accept-Encoding" + Debug.Assert((_currentBits & 0x400000L) != 0); _current = new KeyValuePair(HeaderNames.GrpcAcceptEncoding, _collection._headers._GrpcAcceptEncoding); - _next = 23; - return true; - } - HeaderGrpcEncoding: // case 23 - if ((_bits & 0x800000L) != 0) - { + _currentBits ^= 0x400000L; + break; + case 23: // Header: "Grpc-Encoding" + Debug.Assert((_currentBits & 0x800000L) != 0); _current = new KeyValuePair(HeaderNames.GrpcEncoding, _collection._headers._GrpcEncoding); - _next = 24; - return true; - } - HeaderGrpcTimeout: // case 24 - if ((_bits & 0x1000000L) != 0) - { + _currentBits ^= 0x800000L; + break; + case 24: // Header: "Grpc-Timeout" + Debug.Assert((_currentBits & 0x1000000L) != 0); _current = new KeyValuePair(HeaderNames.GrpcTimeout, _collection._headers._GrpcTimeout); - _next = 25; - return true; - } - HeaderIfMatch: // case 25 - if ((_bits & 0x2000000L) != 0) - { + _currentBits ^= 0x1000000L; + break; + case 25: // Header: "If-Match" + Debug.Assert((_currentBits & 0x2000000L) != 0); _current = new KeyValuePair(HeaderNames.IfMatch, _collection._headers._IfMatch); - _next = 26; - return true; - } - HeaderIfModifiedSince: // case 26 - if ((_bits & 0x4000000L) != 0) - { + _currentBits ^= 0x2000000L; + break; + case 26: // Header: "If-Modified-Since" + Debug.Assert((_currentBits & 0x4000000L) != 0); _current = new KeyValuePair(HeaderNames.IfModifiedSince, _collection._headers._IfModifiedSince); - _next = 27; - return true; - } - HeaderIfNoneMatch: // case 27 - if ((_bits & 0x8000000L) != 0) - { + _currentBits ^= 0x4000000L; + break; + case 27: // Header: "If-None-Match" + Debug.Assert((_currentBits & 0x8000000L) != 0); _current = new KeyValuePair(HeaderNames.IfNoneMatch, _collection._headers._IfNoneMatch); - _next = 28; - return true; - } - HeaderIfRange: // case 28 - if ((_bits & 0x10000000L) != 0) - { + _currentBits ^= 0x8000000L; + break; + case 28: // Header: "If-Range" + Debug.Assert((_currentBits & 0x10000000L) != 0); _current = new KeyValuePair(HeaderNames.IfRange, _collection._headers._IfRange); - _next = 29; - return true; - } - HeaderIfUnmodifiedSince: // case 29 - if ((_bits & 0x20000000L) != 0) - { + _currentBits ^= 0x10000000L; + break; + case 29: // Header: "If-Unmodified-Since" + Debug.Assert((_currentBits & 0x20000000L) != 0); _current = new KeyValuePair(HeaderNames.IfUnmodifiedSince, _collection._headers._IfUnmodifiedSince); - _next = 30; - return true; - } - HeaderKeepAlive: // case 30 - if ((_bits & 0x40000000L) != 0) - { + _currentBits ^= 0x20000000L; + break; + case 30: // Header: "Keep-Alive" + Debug.Assert((_currentBits & 0x40000000L) != 0); _current = new KeyValuePair(HeaderNames.KeepAlive, _collection._headers._KeepAlive); - _next = 31; - return true; - } - HeaderMaxForwards: // case 31 - if ((_bits & 0x80000000L) != 0) - { + _currentBits ^= 0x40000000L; + break; + case 31: // Header: "Max-Forwards" + Debug.Assert((_currentBits & 0x80000000L) != 0); _current = new KeyValuePair(HeaderNames.MaxForwards, _collection._headers._MaxForwards); - _next = 32; - return true; - } - HeaderOrigin: // case 32 - if ((_bits & 0x100000000L) != 0) - { + _currentBits ^= 0x80000000L; + break; + case 32: // Header: "Origin" + Debug.Assert((_currentBits & 0x100000000L) != 0); _current = new KeyValuePair(HeaderNames.Origin, _collection._headers._Origin); - _next = 33; - return true; - } - HeaderPragma: // case 33 - if ((_bits & 0x200000000L) != 0) - { + _currentBits ^= 0x100000000L; + break; + case 33: // Header: "Pragma" + Debug.Assert((_currentBits & 0x200000000L) != 0); _current = new KeyValuePair(HeaderNames.Pragma, _collection._headers._Pragma); - _next = 34; - return true; - } - HeaderProxyAuthorization: // case 34 - if ((_bits & 0x400000000L) != 0) - { + _currentBits ^= 0x200000000L; + break; + case 34: // Header: "Proxy-Authorization" + Debug.Assert((_currentBits & 0x400000000L) != 0); _current = new KeyValuePair(HeaderNames.ProxyAuthorization, _collection._headers._ProxyAuthorization); - _next = 35; - return true; - } - HeaderRange: // case 35 - if ((_bits & 0x800000000L) != 0) - { + _currentBits ^= 0x400000000L; + break; + case 35: // Header: "Range" + Debug.Assert((_currentBits & 0x800000000L) != 0); _current = new KeyValuePair(HeaderNames.Range, _collection._headers._Range); - _next = 36; - return true; - } - HeaderReferer: // case 36 - if ((_bits & 0x1000000000L) != 0) - { + _currentBits ^= 0x800000000L; + break; + case 36: // Header: "Referer" + Debug.Assert((_currentBits & 0x1000000000L) != 0); _current = new KeyValuePair(HeaderNames.Referer, _collection._headers._Referer); - _next = 37; - return true; - } - HeaderRequestId: // case 37 - if ((_bits & 0x2000000000L) != 0) - { + _currentBits ^= 0x1000000000L; + break; + case 37: // Header: "Request-Id" + Debug.Assert((_currentBits & 0x2000000000L) != 0); _current = new KeyValuePair(HeaderNames.RequestId, _collection._headers._RequestId); - _next = 38; - return true; - } - HeaderTE: // case 38 - if ((_bits & 0x4000000000L) != 0) - { + _currentBits ^= 0x2000000000L; + break; + case 38: // Header: "TE" + Debug.Assert((_currentBits & 0x4000000000L) != 0); _current = new KeyValuePair(HeaderNames.TE, _collection._headers._TE); - _next = 39; - return true; - } - HeaderTraceParent: // case 39 - if ((_bits & 0x8000000000L) != 0) - { + _currentBits ^= 0x4000000000L; + break; + case 39: // Header: "traceparent" + Debug.Assert((_currentBits & 0x8000000000L) != 0); _current = new KeyValuePair(HeaderNames.TraceParent, _collection._headers._TraceParent); - _next = 40; - return true; - } - HeaderTraceState: // case 40 - if ((_bits & 0x10000000000L) != 0) - { + _currentBits ^= 0x8000000000L; + break; + case 40: // Header: "tracestate" + Debug.Assert((_currentBits & 0x10000000000L) != 0); _current = new KeyValuePair(HeaderNames.TraceState, _collection._headers._TraceState); - _next = 41; - return true; - } - HeaderTransferEncoding: // case 41 - if ((_bits & 0x20000000000L) != 0) - { + _currentBits ^= 0x10000000000L; + break; + case 41: // Header: "Transfer-Encoding" + Debug.Assert((_currentBits & 0x20000000000L) != 0); _current = new KeyValuePair(HeaderNames.TransferEncoding, _collection._headers._TransferEncoding); - _next = 42; - return true; - } - HeaderTranslate: // case 42 - if ((_bits & 0x40000000000L) != 0) - { + _currentBits ^= 0x20000000000L; + break; + case 42: // Header: "Translate" + Debug.Assert((_currentBits & 0x40000000000L) != 0); _current = new KeyValuePair(HeaderNames.Translate, _collection._headers._Translate); - _next = 43; - return true; - } - HeaderUpgrade: // case 43 - if ((_bits & 0x80000000000L) != 0) - { + _currentBits ^= 0x40000000000L; + break; + case 43: // Header: "Upgrade" + Debug.Assert((_currentBits & 0x80000000000L) != 0); _current = new KeyValuePair(HeaderNames.Upgrade, _collection._headers._Upgrade); - _next = 44; - return true; - } - HeaderUpgradeInsecureRequests: // case 44 - if ((_bits & 0x100000000000L) != 0) - { + _currentBits ^= 0x80000000000L; + break; + case 44: // Header: "Upgrade-Insecure-Requests" + Debug.Assert((_currentBits & 0x100000000000L) != 0); _current = new KeyValuePair(HeaderNames.UpgradeInsecureRequests, _collection._headers._UpgradeInsecureRequests); - _next = 45; - return true; - } - HeaderVia: // case 45 - if ((_bits & 0x200000000000L) != 0) - { + _currentBits ^= 0x100000000000L; + break; + case 45: // Header: "Via" + Debug.Assert((_currentBits & 0x200000000000L) != 0); _current = new KeyValuePair(HeaderNames.Via, _collection._headers._Via); - _next = 46; - return true; - } - HeaderWarning: // case 46 - if ((_bits & 0x400000000000L) != 0) - { + _currentBits ^= 0x200000000000L; + break; + case 46: // Header: "Warning" + Debug.Assert((_currentBits & 0x400000000000L) != 0); _current = new KeyValuePair(HeaderNames.Warning, _collection._headers._Warning); - _next = 47; + _currentBits ^= 0x400000000000L; + break; + case 47: // Header: "Content-Length" + Debug.Assert(_currentBits == 0); + _current = new KeyValuePair(HeaderNames.ContentLength, HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.GetValueOrDefault())); + _next = -1; return true; - } - HeaderContentLength: // case 47 - if (_collection._contentLength.HasValue) - { - _current = new KeyValuePair(HeaderNames.ContentLength, HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.Value)); - _next = 48; + default: + if (!_hasUnknown || !_unknownEnumerator.MoveNext()) + { + _current = default(KeyValuePair); + return false; + } + _current = _unknownEnumerator.Current; return true; - } - ExtraHeaders: - if (!_hasUnknown || !_unknownEnumerator.MoveNext()) - { - _current = default(KeyValuePair); - return false; - } - _current = _unknownEnumerator.Current; + } + + if (_currentBits != 0) + { + _next = BitOperations.TrailingZeroCount(_currentBits); return true; + } + else + { + _next = _collection._contentLength.HasValue ? 47 : -1; + return true; + } } } } @@ -14825,410 +14641,262 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { switch (_next) { - case 0: - goto HeaderConnection; - case 1: - goto HeaderContentType; - case 2: - goto HeaderDate; - case 3: - goto HeaderServer; - case 4: - goto HeaderAcceptRanges; - case 5: - goto HeaderAccessControlAllowCredentials; - case 6: - goto HeaderAccessControlAllowHeaders; - case 7: - goto HeaderAccessControlAllowMethods; - case 8: - goto HeaderAccessControlAllowOrigin; - case 9: - goto HeaderAccessControlExposeHeaders; - case 10: - goto HeaderAccessControlMaxAge; - case 11: - goto HeaderAge; - case 12: - goto HeaderAllow; - case 13: - goto HeaderAltSvc; - case 14: - goto HeaderCacheControl; - case 15: - goto HeaderContentEncoding; - case 16: - goto HeaderContentLanguage; - case 17: - goto HeaderContentLocation; - case 18: - goto HeaderContentMD5; - case 19: - goto HeaderContentRange; - case 20: - goto HeaderETag; - case 21: - goto HeaderExpires; - case 22: - goto HeaderGrpcEncoding; - case 23: - goto HeaderKeepAlive; - case 24: - goto HeaderLastModified; - case 25: - goto HeaderLocation; - case 26: - goto HeaderPragma; - case 27: - goto HeaderProxyAuthenticate; - case 28: - goto HeaderProxyConnection; - case 29: - goto HeaderRetryAfter; - case 30: - goto HeaderSetCookie; - case 31: - goto HeaderTrailer; - case 32: - goto HeaderTransferEncoding; - case 33: - goto HeaderUpgrade; - case 34: - goto HeaderVary; - case 35: - goto HeaderVia; - case 36: - goto HeaderWarning; - case 37: - goto HeaderWWWAuthenticate; - case 38: - goto HeaderContentLength; - default: - goto ExtraHeaders; - } - - HeaderConnection: // case 0 - if ((_bits & 0x1L) != 0) - { + case 0: // Header: "Connection" + Debug.Assert((_currentBits & 0x1L) != 0); _current = new KeyValuePair(HeaderNames.Connection, _collection._headers._Connection); _currentKnownType = KnownHeaderType.Connection; - _next = 1; - return true; - } - HeaderContentType: // case 1 - if ((_bits & 0x2L) != 0) - { + _currentBits ^= 0x1L; + break; + case 1: // Header: "Content-Type" + Debug.Assert((_currentBits & 0x2L) != 0); _current = new KeyValuePair(HeaderNames.ContentType, _collection._headers._ContentType); _currentKnownType = KnownHeaderType.ContentType; - _next = 2; - return true; - } - HeaderDate: // case 2 - if ((_bits & 0x4L) != 0) - { + _currentBits ^= 0x2L; + break; + case 2: // Header: "Date" + Debug.Assert((_currentBits & 0x4L) != 0); _current = new KeyValuePair(HeaderNames.Date, _collection._headers._Date); _currentKnownType = KnownHeaderType.Date; - _next = 3; - return true; - } - HeaderServer: // case 3 - if ((_bits & 0x8L) != 0) - { + _currentBits ^= 0x4L; + break; + case 3: // Header: "Server" + Debug.Assert((_currentBits & 0x8L) != 0); _current = new KeyValuePair(HeaderNames.Server, _collection._headers._Server); _currentKnownType = KnownHeaderType.Server; - _next = 4; - return true; - } - HeaderAcceptRanges: // case 4 - if ((_bits & 0x10L) != 0) - { + _currentBits ^= 0x8L; + break; + case 4: // Header: "Accept-Ranges" + Debug.Assert((_currentBits & 0x10L) != 0); _current = new KeyValuePair(HeaderNames.AcceptRanges, _collection._headers._AcceptRanges); _currentKnownType = KnownHeaderType.AcceptRanges; - _next = 5; - return true; - } - HeaderAccessControlAllowCredentials: // case 5 - if ((_bits & 0x20L) != 0) - { + _currentBits ^= 0x10L; + break; + case 5: // Header: "Access-Control-Allow-Credentials" + Debug.Assert((_currentBits & 0x20L) != 0); _current = new KeyValuePair(HeaderNames.AccessControlAllowCredentials, _collection._headers._AccessControlAllowCredentials); _currentKnownType = KnownHeaderType.AccessControlAllowCredentials; - _next = 6; - return true; - } - HeaderAccessControlAllowHeaders: // case 6 - if ((_bits & 0x40L) != 0) - { + _currentBits ^= 0x20L; + break; + case 6: // Header: "Access-Control-Allow-Headers" + Debug.Assert((_currentBits & 0x40L) != 0); _current = new KeyValuePair(HeaderNames.AccessControlAllowHeaders, _collection._headers._AccessControlAllowHeaders); _currentKnownType = KnownHeaderType.AccessControlAllowHeaders; - _next = 7; - return true; - } - HeaderAccessControlAllowMethods: // case 7 - if ((_bits & 0x80L) != 0) - { + _currentBits ^= 0x40L; + break; + case 7: // Header: "Access-Control-Allow-Methods" + Debug.Assert((_currentBits & 0x80L) != 0); _current = new KeyValuePair(HeaderNames.AccessControlAllowMethods, _collection._headers._AccessControlAllowMethods); _currentKnownType = KnownHeaderType.AccessControlAllowMethods; - _next = 8; - return true; - } - HeaderAccessControlAllowOrigin: // case 8 - if ((_bits & 0x100L) != 0) - { + _currentBits ^= 0x80L; + break; + case 8: // Header: "Access-Control-Allow-Origin" + Debug.Assert((_currentBits & 0x100L) != 0); _current = new KeyValuePair(HeaderNames.AccessControlAllowOrigin, _collection._headers._AccessControlAllowOrigin); _currentKnownType = KnownHeaderType.AccessControlAllowOrigin; - _next = 9; - return true; - } - HeaderAccessControlExposeHeaders: // case 9 - if ((_bits & 0x200L) != 0) - { + _currentBits ^= 0x100L; + break; + case 9: // Header: "Access-Control-Expose-Headers" + Debug.Assert((_currentBits & 0x200L) != 0); _current = new KeyValuePair(HeaderNames.AccessControlExposeHeaders, _collection._headers._AccessControlExposeHeaders); _currentKnownType = KnownHeaderType.AccessControlExposeHeaders; - _next = 10; - return true; - } - HeaderAccessControlMaxAge: // case 10 - if ((_bits & 0x400L) != 0) - { + _currentBits ^= 0x200L; + break; + case 10: // Header: "Access-Control-Max-Age" + Debug.Assert((_currentBits & 0x400L) != 0); _current = new KeyValuePair(HeaderNames.AccessControlMaxAge, _collection._headers._AccessControlMaxAge); _currentKnownType = KnownHeaderType.AccessControlMaxAge; - _next = 11; - return true; - } - HeaderAge: // case 11 - if ((_bits & 0x800L) != 0) - { + _currentBits ^= 0x400L; + break; + case 11: // Header: "Age" + Debug.Assert((_currentBits & 0x800L) != 0); _current = new KeyValuePair(HeaderNames.Age, _collection._headers._Age); _currentKnownType = KnownHeaderType.Age; - _next = 12; - return true; - } - HeaderAllow: // case 12 - if ((_bits & 0x1000L) != 0) - { + _currentBits ^= 0x800L; + break; + case 12: // Header: "Allow" + Debug.Assert((_currentBits & 0x1000L) != 0); _current = new KeyValuePair(HeaderNames.Allow, _collection._headers._Allow); _currentKnownType = KnownHeaderType.Allow; - _next = 13; - return true; - } - HeaderAltSvc: // case 13 - if ((_bits & 0x2000L) != 0) - { + _currentBits ^= 0x1000L; + break; + case 13: // Header: "Alt-Svc" + Debug.Assert((_currentBits & 0x2000L) != 0); _current = new KeyValuePair(HeaderNames.AltSvc, _collection._headers._AltSvc); _currentKnownType = KnownHeaderType.AltSvc; - _next = 14; - return true; - } - HeaderCacheControl: // case 14 - if ((_bits & 0x4000L) != 0) - { + _currentBits ^= 0x2000L; + break; + case 14: // Header: "Cache-Control" + Debug.Assert((_currentBits & 0x4000L) != 0); _current = new KeyValuePair(HeaderNames.CacheControl, _collection._headers._CacheControl); _currentKnownType = KnownHeaderType.CacheControl; - _next = 15; - return true; - } - HeaderContentEncoding: // case 15 - if ((_bits & 0x8000L) != 0) - { + _currentBits ^= 0x4000L; + break; + case 15: // Header: "Content-Encoding" + Debug.Assert((_currentBits & 0x8000L) != 0); _current = new KeyValuePair(HeaderNames.ContentEncoding, _collection._headers._ContentEncoding); _currentKnownType = KnownHeaderType.ContentEncoding; - _next = 16; - return true; - } - HeaderContentLanguage: // case 16 - if ((_bits & 0x10000L) != 0) - { + _currentBits ^= 0x8000L; + break; + case 16: // Header: "Content-Language" + Debug.Assert((_currentBits & 0x10000L) != 0); _current = new KeyValuePair(HeaderNames.ContentLanguage, _collection._headers._ContentLanguage); _currentKnownType = KnownHeaderType.ContentLanguage; - _next = 17; - return true; - } - HeaderContentLocation: // case 17 - if ((_bits & 0x20000L) != 0) - { + _currentBits ^= 0x10000L; + break; + case 17: // Header: "Content-Location" + Debug.Assert((_currentBits & 0x20000L) != 0); _current = new KeyValuePair(HeaderNames.ContentLocation, _collection._headers._ContentLocation); _currentKnownType = KnownHeaderType.ContentLocation; - _next = 18; - return true; - } - HeaderContentMD5: // case 18 - if ((_bits & 0x40000L) != 0) - { + _currentBits ^= 0x20000L; + break; + case 18: // Header: "Content-MD5" + Debug.Assert((_currentBits & 0x40000L) != 0); _current = new KeyValuePair(HeaderNames.ContentMD5, _collection._headers._ContentMD5); _currentKnownType = KnownHeaderType.ContentMD5; - _next = 19; - return true; - } - HeaderContentRange: // case 19 - if ((_bits & 0x80000L) != 0) - { + _currentBits ^= 0x40000L; + break; + case 19: // Header: "Content-Range" + Debug.Assert((_currentBits & 0x80000L) != 0); _current = new KeyValuePair(HeaderNames.ContentRange, _collection._headers._ContentRange); _currentKnownType = KnownHeaderType.ContentRange; - _next = 20; - return true; - } - HeaderETag: // case 20 - if ((_bits & 0x100000L) != 0) - { + _currentBits ^= 0x80000L; + break; + case 20: // Header: "ETag" + Debug.Assert((_currentBits & 0x100000L) != 0); _current = new KeyValuePair(HeaderNames.ETag, _collection._headers._ETag); _currentKnownType = KnownHeaderType.ETag; - _next = 21; - return true; - } - HeaderExpires: // case 21 - if ((_bits & 0x200000L) != 0) - { + _currentBits ^= 0x100000L; + break; + case 21: // Header: "Expires" + Debug.Assert((_currentBits & 0x200000L) != 0); _current = new KeyValuePair(HeaderNames.Expires, _collection._headers._Expires); _currentKnownType = KnownHeaderType.Expires; - _next = 22; - return true; - } - HeaderGrpcEncoding: // case 22 - if ((_bits & 0x400000L) != 0) - { + _currentBits ^= 0x200000L; + break; + case 22: // Header: "Grpc-Encoding" + Debug.Assert((_currentBits & 0x400000L) != 0); _current = new KeyValuePair(HeaderNames.GrpcEncoding, _collection._headers._GrpcEncoding); _currentKnownType = KnownHeaderType.GrpcEncoding; - _next = 23; - return true; - } - HeaderKeepAlive: // case 23 - if ((_bits & 0x800000L) != 0) - { + _currentBits ^= 0x400000L; + break; + case 23: // Header: "Keep-Alive" + Debug.Assert((_currentBits & 0x800000L) != 0); _current = new KeyValuePair(HeaderNames.KeepAlive, _collection._headers._KeepAlive); _currentKnownType = KnownHeaderType.KeepAlive; - _next = 24; - return true; - } - HeaderLastModified: // case 24 - if ((_bits & 0x1000000L) != 0) - { + _currentBits ^= 0x800000L; + break; + case 24: // Header: "Last-Modified" + Debug.Assert((_currentBits & 0x1000000L) != 0); _current = new KeyValuePair(HeaderNames.LastModified, _collection._headers._LastModified); _currentKnownType = KnownHeaderType.LastModified; - _next = 25; - return true; - } - HeaderLocation: // case 25 - if ((_bits & 0x2000000L) != 0) - { + _currentBits ^= 0x1000000L; + break; + case 25: // Header: "Location" + Debug.Assert((_currentBits & 0x2000000L) != 0); _current = new KeyValuePair(HeaderNames.Location, _collection._headers._Location); _currentKnownType = KnownHeaderType.Location; - _next = 26; - return true; - } - HeaderPragma: // case 26 - if ((_bits & 0x4000000L) != 0) - { + _currentBits ^= 0x2000000L; + break; + case 26: // Header: "Pragma" + Debug.Assert((_currentBits & 0x4000000L) != 0); _current = new KeyValuePair(HeaderNames.Pragma, _collection._headers._Pragma); _currentKnownType = KnownHeaderType.Pragma; - _next = 27; - return true; - } - HeaderProxyAuthenticate: // case 27 - if ((_bits & 0x8000000L) != 0) - { + _currentBits ^= 0x4000000L; + break; + case 27: // Header: "Proxy-Authenticate" + Debug.Assert((_currentBits & 0x8000000L) != 0); _current = new KeyValuePair(HeaderNames.ProxyAuthenticate, _collection._headers._ProxyAuthenticate); _currentKnownType = KnownHeaderType.ProxyAuthenticate; - _next = 28; - return true; - } - HeaderProxyConnection: // case 28 - if ((_bits & 0x10000000L) != 0) - { + _currentBits ^= 0x8000000L; + break; + case 28: // Header: "Proxy-Connection" + Debug.Assert((_currentBits & 0x10000000L) != 0); _current = new KeyValuePair(HeaderNames.ProxyConnection, _collection._headers._ProxyConnection); _currentKnownType = KnownHeaderType.ProxyConnection; - _next = 29; - return true; - } - HeaderRetryAfter: // case 29 - if ((_bits & 0x20000000L) != 0) - { + _currentBits ^= 0x10000000L; + break; + case 29: // Header: "Retry-After" + Debug.Assert((_currentBits & 0x20000000L) != 0); _current = new KeyValuePair(HeaderNames.RetryAfter, _collection._headers._RetryAfter); _currentKnownType = KnownHeaderType.RetryAfter; - _next = 30; - return true; - } - HeaderSetCookie: // case 30 - if ((_bits & 0x40000000L) != 0) - { + _currentBits ^= 0x20000000L; + break; + case 30: // Header: "Set-Cookie" + Debug.Assert((_currentBits & 0x40000000L) != 0); _current = new KeyValuePair(HeaderNames.SetCookie, _collection._headers._SetCookie); _currentKnownType = KnownHeaderType.SetCookie; - _next = 31; - return true; - } - HeaderTrailer: // case 31 - if ((_bits & 0x80000000L) != 0) - { + _currentBits ^= 0x40000000L; + break; + case 31: // Header: "Trailer" + Debug.Assert((_currentBits & 0x80000000L) != 0); _current = new KeyValuePair(HeaderNames.Trailer, _collection._headers._Trailer); _currentKnownType = KnownHeaderType.Trailer; - _next = 32; - return true; - } - HeaderTransferEncoding: // case 32 - if ((_bits & 0x100000000L) != 0) - { + _currentBits ^= 0x80000000L; + break; + case 32: // Header: "Transfer-Encoding" + Debug.Assert((_currentBits & 0x100000000L) != 0); _current = new KeyValuePair(HeaderNames.TransferEncoding, _collection._headers._TransferEncoding); _currentKnownType = KnownHeaderType.TransferEncoding; - _next = 33; - return true; - } - HeaderUpgrade: // case 33 - if ((_bits & 0x200000000L) != 0) - { + _currentBits ^= 0x100000000L; + break; + case 33: // Header: "Upgrade" + Debug.Assert((_currentBits & 0x200000000L) != 0); _current = new KeyValuePair(HeaderNames.Upgrade, _collection._headers._Upgrade); _currentKnownType = KnownHeaderType.Upgrade; - _next = 34; - return true; - } - HeaderVary: // case 34 - if ((_bits & 0x400000000L) != 0) - { + _currentBits ^= 0x200000000L; + break; + case 34: // Header: "Vary" + Debug.Assert((_currentBits & 0x400000000L) != 0); _current = new KeyValuePair(HeaderNames.Vary, _collection._headers._Vary); _currentKnownType = KnownHeaderType.Vary; - _next = 35; - return true; - } - HeaderVia: // case 35 - if ((_bits & 0x800000000L) != 0) - { + _currentBits ^= 0x400000000L; + break; + case 35: // Header: "Via" + Debug.Assert((_currentBits & 0x800000000L) != 0); _current = new KeyValuePair(HeaderNames.Via, _collection._headers._Via); _currentKnownType = KnownHeaderType.Via; - _next = 36; - return true; - } - HeaderWarning: // case 36 - if ((_bits & 0x1000000000L) != 0) - { + _currentBits ^= 0x800000000L; + break; + case 36: // Header: "Warning" + Debug.Assert((_currentBits & 0x1000000000L) != 0); _current = new KeyValuePair(HeaderNames.Warning, _collection._headers._Warning); _currentKnownType = KnownHeaderType.Warning; - _next = 37; - return true; - } - HeaderWWWAuthenticate: // case 37 - if ((_bits & 0x2000000000L) != 0) - { + _currentBits ^= 0x1000000000L; + break; + case 37: // Header: "WWW-Authenticate" + Debug.Assert((_currentBits & 0x2000000000L) != 0); _current = new KeyValuePair(HeaderNames.WWWAuthenticate, _collection._headers._WWWAuthenticate); _currentKnownType = KnownHeaderType.WWWAuthenticate; - _next = 38; - return true; - } - HeaderContentLength: // case 38 - if (_collection._contentLength.HasValue) - { - _current = new KeyValuePair(HeaderNames.ContentLength, HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.Value)); + _currentBits ^= 0x2000000000L; + break; + case 38: // Header: "Content-Length" + Debug.Assert(_currentBits == 0); + _current = new KeyValuePair(HeaderNames.ContentLength, HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.GetValueOrDefault())); _currentKnownType = KnownHeaderType.ContentLength; - _next = 39; + _next = -1; return true; - } - ExtraHeaders: - if (!_hasUnknown || !_unknownEnumerator.MoveNext()) - { - _current = default(KeyValuePair); - _currentKnownType = default; - return false; - } - _current = _unknownEnumerator.Current; - _currentKnownType = KnownHeaderType.Unknown; + default: + if (!_hasUnknown || !_unknownEnumerator.MoveNext()) + { + _current = default(KeyValuePair); + _currentKnownType = default; + return false; + } + _current = _unknownEnumerator.Current; + _currentKnownType = KnownHeaderType.Unknown; + return true; + } + + if (_currentBits != 0) + { + _next = BitOperations.TrailingZeroCount(_currentBits); return true; + } + else + { + _next = _collection._contentLength.HasValue ? 38 : -1; + return true; + } } } } @@ -17302,53 +16970,48 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { switch (_next) { - case 0: - goto HeaderETag; - case 1: - goto HeaderGrpcMessage; - case 2: - goto HeaderGrpcStatus; - - default: - goto ExtraHeaders; - } - - HeaderETag: // case 0 - if ((_bits & 0x1L) != 0) - { + case 0: // Header: "ETag" + Debug.Assert((_currentBits & 0x1L) != 0); _current = new KeyValuePair(HeaderNames.ETag, _collection._headers._ETag); _currentKnownType = KnownHeaderType.ETag; - _next = 1; - return true; - } - HeaderGrpcMessage: // case 1 - if ((_bits & 0x2L) != 0) - { + _currentBits ^= 0x1L; + break; + case 1: // Header: "Grpc-Message" + Debug.Assert((_currentBits & 0x2L) != 0); _current = new KeyValuePair(HeaderNames.GrpcMessage, _collection._headers._GrpcMessage); _currentKnownType = KnownHeaderType.GrpcMessage; - _next = 2; - return true; - } - HeaderGrpcStatus: // case 2 - if ((_bits & 0x4L) != 0) - { + _currentBits ^= 0x2L; + break; + case 2: // Header: "Grpc-Status" + Debug.Assert((_currentBits & 0x4L) != 0); _current = new KeyValuePair(HeaderNames.GrpcStatus, _collection._headers._GrpcStatus); _currentKnownType = KnownHeaderType.GrpcStatus; - _next = 3; + _currentBits ^= 0x4L; + break; + + default: + if (!_hasUnknown || !_unknownEnumerator.MoveNext()) + { + _current = default(KeyValuePair); + _currentKnownType = default; + return false; + } + _current = _unknownEnumerator.Current; + _currentKnownType = KnownHeaderType.Unknown; return true; - } - - ExtraHeaders: - if (!_hasUnknown || !_unknownEnumerator.MoveNext()) - { - _current = default(KeyValuePair); - _currentKnownType = default; - return false; - } - _current = _unknownEnumerator.Current; - _currentKnownType = KnownHeaderType.Unknown; + } + + if (_currentBits != 0) + { + _next = BitOperations.TrailingZeroCount(_currentBits); return true; + } + else + { + _next = -1; + return true; + } } } } -} \ No newline at end of file +} diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs index 0386a1638b7..e27fbcf5560 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs @@ -6,6 +6,7 @@ using System.Buffers.Text; using System.Collections; using System.Collections.Generic; using System.Globalization; +using System.Numerics; using System.Runtime.CompilerServices; using System.Text; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; @@ -222,7 +223,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public partial struct Enumerator : IEnumerator> { private readonly HttpRequestHeaders _collection; - private readonly long _bits; + private long _currentBits; private int _next; private KeyValuePair _current; private readonly bool _hasUnknown; @@ -231,8 +232,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http internal Enumerator(HttpRequestHeaders collection) { _collection = collection; - _bits = collection._bits; - _next = 0; + _currentBits = collection._bits; + _next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1; _current = default; _hasUnknown = collection.MaybeUnknown != null; _unknownEnumerator = _hasUnknown @@ -250,7 +251,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public void Reset() { - _next = 0; + _currentBits = _collection._bits; + _next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1; } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs index c60ae1720ab..98a14061e23 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs @@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis; using System.Collections; using System.Collections.Generic; using System.IO.Pipelines; +using System.Numerics; using System.Runtime.CompilerServices; using System.Text; using Microsoft.Extensions.Primitives; @@ -142,7 +143,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public partial struct Enumerator : IEnumerator> { private readonly HttpResponseHeaders _collection; - private readonly long _bits; + private long _currentBits; private int _next; private KeyValuePair _current; private KnownHeaderType _currentKnownType; @@ -152,8 +153,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http internal Enumerator(HttpResponseHeaders collection) { _collection = collection; - _bits = collection._bits; - _next = 0; + _currentBits = collection._bits; + _next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1; _current = default; _currentKnownType = default; _hasUnknown = collection.MaybeUnknown != null; @@ -174,7 +175,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public void Reset() { - _next = 0; + _currentBits = _collection._bits; + _next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1; } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseTrailers.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseTrailers.cs index 6d908a5b28f..9374a34d4a0 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseTrailers.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseTrailers.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Numerics; using System.Runtime.CompilerServices; using System.Text; using Microsoft.Extensions.Primitives; @@ -50,7 +51,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public partial struct Enumerator : IEnumerator> { private readonly HttpResponseTrailers _collection; - private readonly long _bits; + private long _currentBits; private int _next; private KeyValuePair _current; private KnownHeaderType _currentKnownType; @@ -60,8 +61,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http internal Enumerator(HttpResponseTrailers collection) { _collection = collection; - _bits = collection._bits; - _next = 0; + _currentBits = collection._bits; + _next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1; _current = default; _currentKnownType = default; _hasUnknown = collection.MaybeUnknown != null; @@ -82,7 +83,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public void Reset() { - _next = 0; + _currentBits = _collection._bits; + _next = _currentBits != 0 ? BitOperations.TrailingZeroCount(_currentBits) : -1; } } } diff --git a/src/Servers/Kestrel/shared/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs index b983e33b83d..d42c519fdc2 100644 --- a/src/Servers/Kestrel/shared/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -428,8 +428,9 @@ namespace CodeGenerator public bool EnhancedSetter { get; set; } public bool PrimaryHeader { get; set; } public string FlagBit() => $"{"0x" + (1L << Index).ToString("x", CultureInfo.InvariantCulture)}L"; - public string TestBit() => $"(_bits & {"0x" + (1L << Index).ToString("x", CultureInfo.InvariantCulture)}L) != 0"; - public string TestTempBit() => $"(tempBits & {"0x" + (1L << Index).ToString("x", CultureInfo.InvariantCulture)}L) != 0"; + public string TestBitCore(string name) => $"({name} & {"0x" + (1L << Index).ToString("x", CultureInfo.InvariantCulture)}L) != 0"; + public string TestBit() => TestBitCore("_bits"); + public string TestTempBit() => TestBitCore("tempBits"); public string TestNotTempBit() => $"(tempBits & ~{"0x" + (1L << Index).ToString("x", CultureInfo.InvariantCulture)}L) == 0"; public string TestNotBit() => $"(_bits & {"0x" + (1L << Index).ToString("x", CultureInfo.InvariantCulture)}L) == 0"; public string SetBit() => $"_bits |= {"0x" + (1L << Index).ToString("x", CultureInfo.InvariantCulture)}L"; @@ -1321,40 +1322,40 @@ $@" private void Clear(long bitsToClear) {{ switch (_next) {{{Each(loop.Headers.Where(header => header.Identifier != "ContentLength"), header => $@" - case {header.Index}: - goto Header{header.Identifier};")} - {(!loop.ClassName.Contains("Trailers") ? $@"case {loop.Headers.Length - 1}: - goto HeaderContentLength;" : "")} - default: - goto ExtraHeaders; - }} - {Each(loop.Headers.Where(header => header.Identifier != "ContentLength"), header => $@" - Header{header.Identifier}: // case {header.Index} - if ({header.TestBit()}) - {{ + case {header.Index}: // Header: ""{header.Name}"" + Debug.Assert({header.TestBitCore("_currentBits")}); _current = new KeyValuePair(HeaderNames.{header.Identifier}, _collection._headers._{header.Identifier}); {(loop.ClassName.Contains("Request") ? "" : @$"_currentKnownType = KnownHeaderType.{header.Identifier}; - ")}_next = {header.Index + 1}; - return true; - }}")} - {(!loop.ClassName.Contains("Trailers") ? $@"HeaderContentLength: // case {loop.Headers.Length - 1} - if (_collection._contentLength.HasValue) - {{ - _current = new KeyValuePair(HeaderNames.ContentLength, HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.Value)); + ")}_currentBits ^= {"0x" + (1L << header.Index).ToString("x", CultureInfo.InvariantCulture)}L; + break;")} + {(!loop.ClassName.Contains("Trailers") ? $@"case {loop.Headers.Length - 1}: // Header: ""Content-Length"" + Debug.Assert(_currentBits == 0); + _current = new KeyValuePair(HeaderNames.ContentLength, HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.GetValueOrDefault())); {(loop.ClassName.Contains("Request") ? "" : @"_currentKnownType = KnownHeaderType.ContentLength; - ")}_next = {loop.Headers.Length}; - return true; - }}" : "")} - ExtraHeaders: - if (!_hasUnknown || !_unknownEnumerator.MoveNext()) - {{ - _current = default(KeyValuePair); - {(loop.ClassName.Contains("Request") ? "" : @"_currentKnownType = default; - ")}return false; - }} - _current = _unknownEnumerator.Current; - {(loop.ClassName.Contains("Request") ? "" : @"_currentKnownType = KnownHeaderType.Unknown; - ")}return true; + ")}_next = -1; + return true;" : "")} + default: + if (!_hasUnknown || !_unknownEnumerator.MoveNext()) + {{ + _current = default(KeyValuePair); + {(loop.ClassName.Contains("Request") ? "" : @"_currentKnownType = default; + ")}return false; + }} + _current = _unknownEnumerator.Current; + {(loop.ClassName.Contains("Request") ? "" : @"_currentKnownType = KnownHeaderType.Unknown; + ")}return true; + }} + + if (_currentBits != 0) + {{ + _next = BitOperations.TrailingZeroCount(_currentBits); + return true; + }} + else + {{ + {(!loop.ClassName.Contains("Trailers") ? $@"_next = _collection._contentLength.HasValue ? {loop.Headers.Length - 1} : -1;" : "_next = -1;")} + return true; + }} }} }} }}