@@ -31,6 +31,7 @@ class Parser {
31
31
private $ oParserSettings ;
32
32
private $ sCharset ;
33
33
private $ iLength ;
34
+ private $ peekCache = null ;
34
35
35
36
public function __construct ($ sText , Settings $ oParserSettings = null ) {
36
37
$ this ->sText = $ sText ;
@@ -268,6 +269,7 @@ private function parseRuleSet($oRuleSet) {
268
269
// We need to “unfind” the matches to the end of the ruleSet as this will be matched later
269
270
if ($ this ->streql ($ this ->substr ($ sConsume , $ this ->strlen ($ sConsume )-1 , 1 ), '} ' )) {
270
271
--$ this ->iCurrentPosition ;
272
+ $ this ->peekCache = null ;
271
273
} else {
272
274
$ this ->consumeWhiteSpace ();
273
275
while ($ this ->comes ('; ' )) {
@@ -446,7 +448,7 @@ private function parseURLValue() {
446
448
}
447
449
return $ oResult ;
448
450
}
449
-
451
+
450
452
/**
451
453
* Tests an identifier for a given value. Since identifiers are all keywords, they can be vendor-prefixed. We need to check for these versions too.
452
454
*/
@@ -468,12 +470,25 @@ private function peek($iLength = 1, $iOffset = 0) {
468
470
if (is_string ($ iOffset )) {
469
471
$ iOffset = $ this ->strlen ($ iOffset );
470
472
}
471
- $ iOffset = $ this ->iCurrentPosition + $ iOffset ;
473
+ if (($ peek = (!$ iOffset && ($ iLength == 1 ))) &&
474
+ !is_null ($ this ->peekCache )) {
475
+ return $ this ->peekCache ;
476
+ }
477
+ if (!is_null ($ this ->peekCache ) &&
478
+ $ iLength == 1 &&
479
+ $ iOffset = 0 ) {
480
+ return $ this ->peekCache ;
481
+ }
482
+ $ iOffset += $ this ->iCurrentPosition ;
472
483
if ($ iOffset >= $ this ->iLength ) {
473
484
return '' ;
474
485
}
475
486
$ iLength = min ($ iLength , $ this ->iLength -$ iOffset );
476
- return $ this ->substr ($ this ->sText , $ iOffset , $ iLength );
487
+ $ out = $ this ->substr ($ this ->sText , $ iOffset , $ iLength );
488
+ if ($ peek ) {
489
+ $ this ->peekCache = $ out ;
490
+ }
491
+ return $ out ;
477
492
}
478
493
479
494
private function consume ($ mValue = 1 ) {
@@ -483,13 +498,15 @@ private function consume($mValue = 1) {
483
498
throw new UnexpectedTokenException ($ mValue , $ this ->peek (max ($ iLength , 5 )));
484
499
}
485
500
$ this ->iCurrentPosition += $ this ->strlen ($ mValue );
501
+ $ this ->peekCache = null ;
486
502
return $ mValue ;
487
503
} else {
488
504
if ($ this ->iCurrentPosition + $ mValue > $ this ->iLength ) {
489
505
throw new UnexpectedTokenException ($ mValue , $ this ->peek (5 ), 'count ' );
490
506
}
491
507
$ sResult = $ this ->substr ($ this ->sText , $ this ->iCurrentPosition , $ mValue );
492
508
$ this ->iCurrentPosition += $ mValue ;
509
+ $ this ->peekCache = null ;
493
510
return $ sResult ;
494
511
}
495
512
}
0 commit comments