11using System ;
22
3- namespace TurnerSoftware . CascadingStyles
3+ namespace TurnerSoftware . CascadingStyles . Parsing
44{
55 /// <summary>
66 /// Provides CSS tokenization support, closely following the <a href="https://drafts.csswg.org/css-syntax/#tokenization">official CSS specification</a>.
@@ -15,15 +15,15 @@ namespace TurnerSoftware.CascadingStyles
1515 /// These deviations from the standard allow the tokenizer to be allocation-free in its processing.
1616 /// </para>
1717 /// </remarks>
18- public ref struct CssReader
18+ public struct CssTokenizer
1919 {
2020 public const char EndOfFile = char . MaxValue ;
2121
22- private readonly ReadOnlySpan < char > InputStream ;
22+ private readonly ReadOnlyMemory < char > InputStream ;
2323 private int RegionStartIndex ;
2424 private int IndexOffset ;
2525
26- public CssReader ( ReadOnlySpan < char > value )
26+ public CssTokenizer ( ReadOnlyMemory < char > value )
2727 {
2828 InputStream = value ;
2929 RegionStartIndex = 0 ;
@@ -38,7 +38,7 @@ private char Current
3838 {
3939 if ( CurrentIndex < InputStream . Length )
4040 {
41- return InputStream [ CurrentIndex ] ;
41+ return InputStream . Span [ CurrentIndex ] ;
4242 }
4343
4444 return EndOfFile ;
@@ -48,14 +48,14 @@ private char Current
4848 /// <summary>
4949 /// The unconsumed "remaining" input stream data
5050 /// </summary>
51- private ReadOnlySpan < char > RemainingInputStream => InputStream [ CurrentIndex .. ] ;
51+ private ReadOnlyMemory < char > RemainingInputStream => InputStream . Slice ( CurrentIndex ) ;
5252
5353 private char Peek ( int distance = 1 )
5454 {
5555 var nextIndex = CurrentIndex + distance ;
5656 if ( nextIndex < InputStream . Length )
5757 {
58- return InputStream [ nextIndex ] ;
58+ return InputStream . Span [ nextIndex ] ;
5959 }
6060
6161 return EndOfFile ;
@@ -65,17 +65,17 @@ private char Peek(int distance = 1)
6565 /// Returns the region starting from <see cref="RegionStartIndex"/> to, but not including, <see cref="CurrentIndex"/>.
6666 /// </summary>
6767 /// <returns></returns>
68- private ReadOnlySpan < char > GetRegion ( )
68+ private ReadOnlyMemory < char > GetRegion ( )
6969 {
70- return InputStream [ RegionStartIndex .. CurrentIndex ] ;
70+ return InputStream . Slice ( RegionStartIndex , IndexOffset ) ;
7171 }
7272
7373 /// <summary>
7474 /// Finalizes the current region and starts a new region.
7575 /// Region is from <see cref="RegionStartIndex"/> to, but not including, <see cref="CurrentIndex"/>.
7676 /// </summary>
7777 /// <returns></returns>
78- private ReadOnlySpan < char > ConsumeRegion ( )
78+ private ReadOnlyMemory < char > ConsumeRegion ( )
7979 {
8080 var result = GetRegion ( ) ;
8181 StartNewCaptureRegion ( ) ;
@@ -136,7 +136,7 @@ public bool NextToken(out CssToken token)
136136 {
137137 if ( RegionStartIndex == InputStream . Length )
138138 {
139- token = default ;
139+ token = CssToken . EndOfFile ;
140140 return false ;
141141 }
142142
@@ -248,7 +248,7 @@ public bool NextToken(out CssToken token)
248248 }
249249 else
250250 {
251- token = default ;
251+ token = CssToken . EndOfFile ;
252252 return false ;
253253 }
254254 break ;
@@ -266,7 +266,7 @@ private void ConsumeCommentsIfAny()
266266 // followed by a U+002F SOLIDUS (/), or up to an EOF code point.
267267 if ( Current == '/' && Peek ( ) == '*' )
268268 {
269- var matchIndex = RemainingInputStream . IndexOf ( "*/" ) ;
269+ var matchIndex = RemainingInputStream . Span . IndexOf ( "*/" ) ;
270270 // No closing comment found / it closes at the end of the file
271271 if ( matchIndex == - 1 )
272272 {
@@ -531,7 +531,7 @@ private CssToken ConsumeIdentifierLikeToToken()
531531 var identifier = ConsumeIdentifier ( ) ;
532532
533533 // If identifier matches "url" (case-insensitive) and the next input code point is U+0028 LEFT PARENTHESIS, consume it
534- if ( identifier . Equals ( "url" , StringComparison . OrdinalIgnoreCase ) && Current == '(' )
534+ if ( identifier . Span . Equals ( "url" , StringComparison . OrdinalIgnoreCase ) && Current == '(' )
535535 {
536536 ConsumeCurrent ( ) ;
537537
@@ -654,10 +654,12 @@ private CssToken ConsumeUrlToToken()
654654 /// <returns></returns>
655655 private CssToken ConsumeRemnantsOfBadUrlToToken ( )
656656 {
657+ var remainingInputSpan = RemainingInputStream . Span ;
658+
657659 // Repeatedly consume the next input code point from the stream:
658660 while ( true )
659661 {
660- var nextRightParenthesis = RemainingInputStream . IndexOf ( ')' ) ;
662+ var nextRightParenthesis = remainingInputSpan . IndexOf ( ')' ) ;
661663
662664 // If a U+0029 RIGHT PARENTHESIS ()) or EOF is found, consume and return
663665 // In this case, if no right parenthesis is found, we can jump to the EOF
@@ -671,7 +673,7 @@ private CssToken ConsumeRemnantsOfBadUrlToToken()
671673 // Consume an escaped code point. This allows an escaped right parenthesis ("\)")
672674 // to be encountered without ending the <bad-url-token>.
673675 // We backtrack from the index of the right parenthesis to check
674- var isEscaped = nextRightParenthesis > 0 && RemainingInputStream [ nextRightParenthesis - 1 ] == '\\ ' ;
676+ var isEscaped = nextRightParenthesis > 0 && remainingInputSpan [ nextRightParenthesis - 1 ] == '\\ ' ;
675677
676678 // Either way, we consume all the characters we've found
677679 ConsumeNext ( nextRightParenthesis + 1 ) ;
@@ -693,7 +695,7 @@ private CssToken ConsumeRemnantsOfBadUrlToToken()
693695 /// </summary>
694696 /// <param name="seenDecimal"></param>
695697 /// <returns></returns>
696- private void ConsumeNumber ( out ReadOnlySpan < char > number , out CssTokenFlag flags )
698+ private void ConsumeNumber ( out ReadOnlyMemory < char > number , out CssTokenFlag flags )
697699 {
698700 var startIndex = CurrentIndex ;
699701
@@ -757,7 +759,7 @@ private void ConsumeNumber(out ReadOnlySpan<char> number, out CssTokenFlag flags
757759 /// Assumes that <see cref="Current"/> is the start of the identifier.
758760 /// </remarks>
759761 /// <returns></returns>
760- private ReadOnlySpan < char > ConsumeIdentifier ( )
762+ private ReadOnlyMemory < char > ConsumeIdentifier ( )
761763 {
762764 var startIndex = CurrentIndex ;
763765 while ( true )
0 commit comments