26
26
*/
27
27
class Parser {
28
28
29
- private $ sText ;
29
+ private $ aText ;
30
30
private $ iCurrentPosition ;
31
31
private $ oParserSettings ;
32
32
private $ sCharset ;
@@ -36,12 +36,16 @@ class Parser {
36
36
private $ aSizeUnits ;
37
37
38
38
public function __construct ($ sText , Settings $ oParserSettings = null ) {
39
- $ this ->sText = $ sText ;
40
39
$ this ->iCurrentPosition = 0 ;
41
40
if ($ oParserSettings === null ) {
42
41
$ oParserSettings = Settings::create ();
43
42
}
44
43
$ this ->oParserSettings = $ oParserSettings ;
44
+ if ($ this ->oParserSettings ->bMultibyteSupport ) {
45
+ $ this ->aText = preg_split ('//u ' , $ sText , null , PREG_SPLIT_NO_EMPTY );
46
+ } else {
47
+ $ this ->aText = str_split ($ sText );
48
+ }
45
49
$ this ->blockRules = explode ('/ ' , AtRule::BLOCK_RULES );
46
50
47
51
foreach (explode ('/ ' , Size::ABSOLUTE_SIZE_UNITS .'/ ' .Size::RELATIVE_SIZE_UNITS .'/ ' .Size::NON_SIZE_UNITS ) as $ val ) {
@@ -56,7 +60,7 @@ public function __construct($sText, Settings $oParserSettings = null) {
56
60
57
61
public function setCharset ($ sCharset ) {
58
62
$ this ->sCharset = $ sCharset ;
59
- $ this ->iLength = $ this -> strlen ($ this ->sText );
63
+ $ this ->iLength = count ($ this ->aText );
60
64
}
61
65
62
66
public function getCharset () {
@@ -284,7 +288,7 @@ private function parseRuleSet($oRuleSet) {
284
288
try {
285
289
$ sConsume = $ this ->consumeUntil (array ("\n" , "; " , '} ' ), true );
286
290
// We need to “unfind” the matches to the end of the ruleSet as this will be matched later
287
- if ($ this ->streql ($ this -> substr ($ sConsume , $ this -> strlen ( $ sConsume )- 1 , 1 ), '} ' )) {
291
+ if ($ this ->streql (substr ($ sConsume , - 1 ), '} ' )) {
288
292
--$ this ->iCurrentPosition ;
289
293
$ this ->peekCache = null ;
290
294
} else {
@@ -469,8 +473,8 @@ private function parseURLValue() {
469
473
}
470
474
471
475
/**
472
- * 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.
473
- */
476
+ * 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.
477
+ */
474
478
private function identifierIs ($ sIdentifier , $ sMatch ) {
475
479
return (strcasecmp ($ sIdentifier , $ sMatch ) === 0 )
476
480
?: preg_match ("/^(- \\w+-)? $ sMatch$/i " , $ sIdentifier ) === 1 ;
@@ -493,7 +497,7 @@ private function peek($iLength = 1, $iOffset = 0) {
493
497
return '' ;
494
498
}
495
499
$ iLength = min ($ iLength , $ this ->iLength -$ iOffset );
496
- $ out = $ this ->substr ($ this -> sText , $ iOffset , $ iLength );
500
+ $ out = $ this ->substr ($ iOffset , $ iLength );
497
501
if ($ peek ) {
498
502
$ this ->peekCache = $ out ;
499
503
}
@@ -503,7 +507,7 @@ private function peek($iLength = 1, $iOffset = 0) {
503
507
private function consume ($ mValue = 1 ) {
504
508
if (is_string ($ mValue )) {
505
509
$ iLength = $ this ->strlen ($ mValue );
506
- if (!$ this ->streql ($ this ->substr ($ this ->sText , $ this -> iCurrentPosition , $ iLength ), $ mValue )) {
510
+ if (!$ this ->streql ($ this ->substr ($ this ->iCurrentPosition , $ iLength ), $ mValue )) {
507
511
throw new UnexpectedTokenException ($ mValue , $ this ->peek (max ($ iLength , 5 )));
508
512
}
509
513
$ this ->iCurrentPosition += $ this ->strlen ($ mValue );
@@ -513,7 +517,7 @@ private function consume($mValue = 1) {
513
517
if ($ this ->iCurrentPosition + $ mValue > $ this ->iLength ) {
514
518
throw new UnexpectedTokenException ($ mValue , $ this ->peek (5 ), 'count ' );
515
519
}
516
- $ sResult = $ this ->substr ($ this ->sText , $ this -> iCurrentPosition , $ mValue );
520
+ $ sResult = $ this ->substr ($ this ->iCurrentPosition , $ mValue );
517
521
$ this ->iCurrentPosition += $ mValue ;
518
522
$ this ->peekCache = null ;
519
523
return $ sResult ;
@@ -587,15 +591,17 @@ private function consumeUntil($aEnd, $bIncludeEnd = false, $consumeEnd = false)
587
591
}
588
592
589
593
private function inputLeft () {
590
- return $ this ->substr ($ this ->sText , $ this -> iCurrentPosition , -1 );
594
+ return $ this ->substr ($ this ->iCurrentPosition , -1 );
591
595
}
592
596
593
- private function substr ($ sString , $ iStart , $ iLength ) {
594
- if ($ this ->oParserSettings ->bMultibyteSupport ) {
595
- return mb_substr ($ sString , $ iStart , $ iLength , $ this ->sCharset );
596
- } else {
597
- return substr ($ sString , $ iStart , $ iLength );
597
+ private function substr ($ iStart , $ iLength ) {
598
+ $ out = '' ;
599
+ while ($ iLength > 0 ) {
600
+ $ out .= $ this ->aText [$ iStart ];
601
+ $ iStart ++;
602
+ $ iLength --;
598
603
}
604
+ return $ out ;
599
605
}
600
606
601
607
private function strlen ($ sString ) {
0 commit comments